如上一篇文章,我们可以通过栈的数据结构实现小括号的匹配,那么只需要稍微修改一下,就可以实现三种括号(){}【】的匹配了。
在这里我想应该重申一下括号匹配的定义,每一个左括号都要有相应的右括号而且有合理的嵌套关系,换句话说,第一个左括号一定和最后一个右括号匹配,最后一个无匹配的左括号一定和遇到的第一个右括号相匹配,所以,{(})这样的字符串显然是不匹配的。
首先,我们需要定义栈的数据结构,不做多叙。
其次,我们要考虑算法部分,在这里,我们输入的字符串并非只有左右的区别,它是有三种不同的括号,类似于上一篇,我们可以依旧将左值压进栈s中,然后定义一个计数器i和一个布尔型变量balanced(上一篇文章已经详细叙述了为什么我们需要它,因为右边的括号太多有可能导致左边是空栈!)然后,只要这个balanced为真,并且所有的左括号都找到了对应 的右括号(栈空),则字符串一定匹配。
下面我们需要处理的最麻烦的部分就是对栈的弹出的处理,不妨思考一下,给下面的输入示例:
”{()}“,此时我们的栈中是什么样子的。
( |
{ |
我们的栈就是上面的表格,如果要弹出,首先弹出的应该是圆括号,也就是说如果下一个读入的字符是右括号,那么它一定是小括号,否则整个字符串一定是不匹配的。
因此,在这里我们多了一个挑战,就是需要有一个匹配函数来断定这栈顶的括号和读取到的括号能不能匹配,如果不能,则直接把balanced改为False。
最后的输出值判断和上一篇一样,不做过多的叙述。
最后来考虑匹配函数,首先,我们可以使用index()来返回两个符号对应的索引值,如果索引值相同,则说明括号是匹配的,同样,我们也可以用循环的遍历来实现matches(),只是复杂度高一些。在这里使用循环代码,因为我当时忘记了index.
class Stack:
def __init__(self):
self.items = []
def isEmpty(self):
return self.items==[]
def push(self,item):
self.items.append(item)
def pop(self):
return self.items.pop()
def peek(self):
return self.items[len(self.items)-1]
def size(self):
return len(self.items)
def parchecker(symbolString):
s = Stack()
balanced = True
i=0
while i<len(symbolString) and balanced:
if symbolString[i] in "([{":
s.push(symbolString[i])
else:
if s.isEmpty():
balanced = False
else:
top = s.pop()
if not matches(top,symbolString[i]):
balanced = False
i = i+1
if balanced and s.isEmpty():
return True
else:
return False
def matches(t,s):
opens = "([{"
closers = ")]}"
p=0
q=0
for o in opens:
if t==opens[p]:
break
else:
p=p+1
for c in closers:
if s==closers[q]:
break
else:
q=q+1
return p==q