栈的应用之括号匹配

在许多正文中都有括号,特别是在表示程序、数学表达式的正文片段里,括号有正确配对问题。作为例子,下面考虑python程序里的括号,在这里可以看到:

  • 存在多种不同的括号,下面只考虑其中三种:圆括号、方括号和花括号。
  • 每种括号都包括一个开括号和一个闭括号,相互对应。括号括起的片段可能嵌套,各种括号应该正确地嵌套并分别配对。

不难总结出检查括号配对的原则:在扫描正文过程中,遇到的闭括号应该与此前最近遇到且尚未获得匹配的开括号配对。如果最近的未匹配开括号与当前闭括号不配对,或者找不到这样的开括号,就是匹配失败,说明这段正文里的括号不配对。

由于存在多种不同的括号对,每种括号都可能出现任意多次,而且还可能嵌套。为了检查是否匹配,扫描中必须保存遇到的开括号。由于写程序时无法预知要处理的正文里会有多少括号需要保存,因此不能用固定数目的变量保存,必须用缓存结构。
由于括号的出现可能嵌套,需要逐对匹配:当前闭括号应该与前面最近的尚未配对的开括号匹配,下一个闭括号应与前面次近的括号匹配。这说明,需要存储的开括号的使用原则是后存人者先使用,符合LIFO原则。
进而,如果一个开括号已配对,就应该删除这个括号,为随后的匹配做好准备。显然,在扫描中,后遇到并保存的开括号将先配对并被删除,这就是按出现的顺序后进先出。这些情况说明,用栈保存遇到的开括号可以正确支持匹配工作。
通过上面分析,处理这个问题的脉络已经很清楚了:

  • 顺序扫描被检查正文(一个字符串)里的一个个字符。
  • 检查中跳过无关字符(所有非括号字符都与当前处理无关)。
  • 遇到开括号时将其压人栈。
  • 遇到闭括号时弹出当时的栈顶元素与之匹配。
  • 如果匹配成功则继续,发现不匹配时检查以失败结束。
def check_parens(text):
    """括号配对检查函数,text是被检查的正文串"""
    parens="()[]{}"     #要检查配对的所有括号
    open_parens="([{"   #开括号
    opposite={")":"(","]":"[","}":"{"}  #表示配对关系的字典

    def parentheses(text):
        """括号生成器,每次调用返回text里的下一括号及其位置"""
        i,text_len=0,len(text)
        while True:
            while i<text_len and text[i] not in parens:
                i+=1
            if i>=text_len:
                return
            yield text[i],i
            i+=1

    st=SStack()                 #栈
    for p,i in parentheses(text):
        if p in open_parens:
            st.push(p)
        else:
            if opposite[p]!=st.pop():
                print("\n匹配失败")
                return False
    print("\n匹配成功")
    return True

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值