is_balance函数优化

来源:互联网 发布:写jquery必须会js么 编辑:程序博客网 时间:2024/06/05 18:12

最近在读《python3程序开发指南》,其中5.1章节P174,is_balance函数有不完善的地方:

函数源码:

def is_balance(text, brackets="()[]{}<>"):    #counts为分别存放左符号的个数的字典    counts = {}    left_for_right = {}    for left, right in zip(brackets[::2], brackets[1::2]):        #此处的断言语法很简洁        assert left != right                #初始化左符号字典        counts[left] = 0        #初始化左右符号字典对        left_for_right[right] = left            for c in text:        #如果出现左符号,在左符号对中的value加1        if c in counts:            counts[c] += 1        elif c in left_for_right:            left = left_for_right[c]            #如果出现右符号,则和左符号进行匹配            if counts[left] == 0:                return False            counts[left] -= 1    return not any(counts.values())stringA = "[(aabbv])"print(stringA)print(is_balance(stringA))
不完善的地方就在于如果出现[(])的情况,尽管数量是正确的,但是由于序列的不对,造成了无法匹配出来。

下面的改进如下:

由于平衡的符号对总是出现左符号,再出现右符号;所以设置一个左符号堆栈,每出现一个左符号就push入堆栈;当出现一个右符号,则从左符号堆栈中pop出来最近的一个进行匹配,这样就实现了对符号序列的匹配,代码如下:

def is_balance_seq(text, brackets="()[]{}<>"):    #左右符号字典对    left_for_right = {}    #定义左符号堆栈    left_item = []    #所有左符号    left_mark = brackets[::2]    #所有右符号    right_mark = brackets[1::2]    #生成左右符号字典对    for left, right in zip(brackets[::2],brackets[1::2]):        assert[left] != right        left_for_right[right] = left       for c in text:        if c in left_mark:            #如果扫描出左符号,进行压栈操作            left_item.append(c)        elif c in right_mark:            #如果扫描出右符号,对左符号栈pop进行匹配,这里要注意空栈            if len(left_item)>0:                left_A = left_item.pop()                if left_for_right[c] != left_A:                    return False            else:                #出现的空栈的原因一定是因为先出现了右符号,这肯定是不符合序列的                return False    return Truedef debug(a):    print(a)StringA = "[(aabbv])"print(StringA)print(is_balance_seq(StringA))

多读书,多敲代码,多实验,多思考。



0 0