3.7.符号匹配

上面显示的匹配括号问题是许多编程语言都会出现的一般情况的特定情况。匹配和嵌套不同种类的开始和结束符号的情况经常发生。例如,在 Python 中,方括号 [] 用于列表,花括号 {} 用于字典。括号 () 用于元组和算术表达式。只要每个符号都能保持自己的开始和结束关系,就可以混合符号。符号字符串如

  1. { { ( [ ] [ ] ) } ( ) }
  2. [ [ { { ( ( ) ) } } ] ]
  3. [ ] [ ] [ ] ( ) { }

这些被恰当的匹配了,因为不仅每个开始符号都有对应的结束符号,而且符号的类型也匹配。

相反这些字符串没法匹配:

  1. ( [ ) ]
  2. ( ( ( ) ] ) )
  3. [ { ( ) ]

上节的简单括号检查程序可以轻松的扩展处理这些新类型的符号。回想一下,每个开始符号被简单的压入栈中,等待匹配的结束符号出现。当出现结束符号时,唯一的区别是我们必须检查确保它正确匹配栈顶部开始符号的类型。如果两个符号不匹配,则字符串不匹配。如果整个字符串都被处理完并且没有什么留在栈中,则字符串匹配。

Python 程序见 ActiveCode 1。唯一的变化是 16 行,我们称之为辅助函数匹配。必须检查栈中每个删除的符号,以查看它是否与当前结束符号匹配。如果不匹配,则布尔变量 balanced 被设置为 False。

  1. from pythonds.basic.stack import Stack
  2. def parChecker(symbolString):
  3. s = Stack()
  4. balanced = True
  5. index = 0
  6. while index < len(symbolString) and balanced:
  7. symbol = symbolString[index]
  8. if symbol in "([{":
  9. s.push(symbol)
  10. else:
  11. if s.isEmpty():
  12. balanced = False
  13. else:
  14. top = s.pop()
  15. if not matches(top,symbol):
  16. balanced = False
  17. index = index + 1
  18. if balanced and s.isEmpty():
  19. return True
  20. else:
  21. return False
  22. def matches(open,close):
  23. opens = "([{"
  24. closers = ")]}"
  25. return opens.index(open) == closers.index(close)
  26. print(parChecker('{{([][])}()}'))
  27. print(parChecker('[{()]'))

ActiveCode 1

这两个例子表明,栈是计算机语言结构处理非常重要的数据结构。几乎你能想到的任何嵌套符号必须按照平衡匹配的顺序。栈还有其他重要的用途,我们将在接下来的部分讨论。