在考虑这个问题前,我们首先复习数据结构中的栈,因为编译器中括号匹配就是通过栈来实现的:
栈:
栈:是一种先进后出的数据结构;其本质也就有特殊限制的链表(先进后出,栈顶),提起栈我们首先会想到什么呢?当然是进栈(push)和出栈(pop),下面我们通过代码来实现进栈和出栈过程:
我们要重视栈顶这个部分:栈顶(top),我们要保证栈顶只有一个节点,并且链接到下面的节点,具体的实现方式是,构建一个新节点,把新节点的next(指针)指向原先的栈顶,再把栈顶设置为新节点。如下面代码所示。
#建立栈结构 push 和 pop
#首先定义listnode
class node(object):
def __init__(self,value=None):
self.value=value
self.next=None
class stack(object):
![](/qrcode.jpg)
def __init__(self):
self.node=node()
self.top=[self.node]
def push(self,elem):
new_node=node(elem)
if self.top[0].value==None:
new_node.next=None
else:
new_node.next=self.top[0]
self.top.append(new_node)
self.top.pop(0)
def pop(self):
try:
value_top=self.top[0].value
node=self.top[0].next
self.top.append(node)
self.top.pop(0)
return value_top
except:
print('wrong')
s=stack()
for i in ['a','b','c','d']:
s.push(i)
for i in range(4):
print(s.pop())
问题和问题分析
问题来源于leetcode,
这个问题可以说非常重要,因为我们程序编译器中常常要检查括号是否配对,如果我们能够真正了解这个原理,能够有助于我们深入了解编译器原理:
我们首先考虑简单的情况:当所有括号类型相同的时候,我们只需要让每个左括号都有一个右括号与其匹配就可以,总结来说,我们将左括号计数(left)有如下公式:
left++left++left++
我们考虑遇到右括号时,left的不同情况:
left=0 说明没有和右括号相匹配的左括号,即表达式是invaild
left>0,我们有与右括号相匹配的左括号,此时匹配我们要将left−−left--left−−
如果遍历完所有的符号后,left!=0,说明表达式依旧是invalid
总而言之,我们只需要计数左括号,看是否有与之匹配的右括号,但是这仅仅是简单的情况,没有考虑到不同符号之间的相对位置,如果是如下这样的表达式,我们上面总结的规律就不满足了:
({)}
进一步考虑
根据一个有趣的规律:郑州妇科医院 http://www.ytsgfk120.com/
关于有效括号表达式的一个有趣属性是有效表达式的子表达式也应该是有效表达式。(不是每个子表达式)。
从这里我们看出是递归的,也就是如果每个子表达式是有效的表达式,整个表达式就是有效的,这样我们就可以从解决每个子表达式出发,当表达式匹配就删除,直至剩下空的表达式说明了表达式是有效的:算法流程如下:
遇到左括号将其压入栈。
遇到右括号,将栈顶推出,如果与栈顶相匹配,继续进行,如果不匹配,则可以判断整个表达式无效(invaild)。
如果最后栈空就说明了,表达式有效,代码如下,用字典的数据结构有助于我们降低复杂度:
#建立栈结构 push 和 pop
#首先定义listnode
class node(object):
def __init__(self,value=None):
self.value=value
self.next=None
class stack(object):
def __init__(self):
self.top=None
def push(self,elem):
new_node=node(elem)
if self.top==None:
new_node.next=None
else:
new_node.next=self.top
self.top=new_node
def pop(self):
if self.top!=None:
value_top=self.top.value
node=self.top.next
self.top=node
return value_top
else:
return False
string='()'
dict_={'}':'{',']':'[',')':'('}
def judge_str(str_,dict_):
s=stack()
for i in str_:
if i in dict_:
result=s.pop() if s.top else '#'
if (result!=dict_[i]):
return False
else:
s.push(i)
if s.top==None:
return True
else:
return False
judge_str(string,dict_)
总结
总结而言,我们括号匹配是一种递归结构,如果每个子表达式匹配,那么整个表达式也匹配,用栈结构来实现它,按照以上总结的规律,用字典格式可以很快很好的解决问题.
遇到左括号将其压入栈。
遇到右括号,将栈顶推出,如果与栈顶相匹配,继续进行,如果不匹配,则可以判断整个表达式无效(invaild)