python实现括号匹配不用栈_Python中的数据结构:堆栈-判断括号是否平衡

本文介绍了如何使用Python的列表实现堆栈数据结构,用于判断括号是否平衡。通过创建Stack类,分别展示了以列表尾部和头部作为堆栈顶部的两种实现。重点讲述了使用堆栈解决平衡括号问题的算法,强调了最近的开括号必须匹配下一个闭合括号,并遵循括号的前后顺序。文章提供了一个名为par_checker的函数,用于检查括号字符串的平衡性。
摘要由CSDN通过智能技术生成

堆栈是处理计算机科学中语言构造的非常重要的数据结构。 我们可以想到的任何符号都有某种嵌套符号,必须以平衡的顺序进行匹配。

堆栈定义

•是已添加项目的有序集合,从同一端添加和移除

•最后添加的项目是第一个删除,也称为后进先出

•最新添加的项目在顶部/顶部,最旧的在底部/后部

自助餐厅都有一叠托盘或盘子,人们可以将新盘子放在旧盘子顶部,为下一个排队的顾客发现新的托盘或盘子。堆叠的书唯一可见封面的书是最上面的书。要访问堆栈中的其他对象,我们首先要删除位于它们顶部的对象。删除的顺序与放置的顺序完全相反。堆栈很重要,因为它们可用于反转项目的顺序。图片来自于http://www.pas.rochester.edu/~rsarkis/csc162/_static/lectures/Stacks.pdf

图片来自于http://www.pas.rochester.edu/~rsarkis/csc162/_static/lectures/Stacks.pdf图片来自于http://www.pas.rochester.edu/~rsarkis/csc162/_static/lectures/Stacks.pdf

堆栈抽象数据类型由以下结构和操作定义。堆栈被构造为项目的有序集合,其中将项目添加到称为“顶部”的末端或从末端移除。堆栈式有序的LIFO。

•Stack()创建一个空的新堆栈。它不需要参数,并返回一个空堆栈。

•push(item)将新项目添加到堆栈顶部。它需要该项目,但不返回任何内容。

•pop()从堆栈中删除顶层项目。它不需要任何参数并返回项目。堆栈已修改。

•peek()返回堆栈顶部的项目,但不会将其删除。它不需要任何参数。堆栈未修改。

•is_empty()测试以查看堆栈是否为空。它不需要任何参数,并返回一个布尔值。

•size()返回堆栈中的项目数。它不需要参数,并返回整数。

与面向对象的编程语言一样,Python选择抽象数据类型(如堆栈)的选择实现是创建新类。 此外,要实现作为元素集合的堆栈,可以利用Python提供的原始集合的强大功能和简单性。 我们将使用列表。Python中的list提供了有序的收集机制和方法。 例如,如果有列表[2、5、3、6、7、4],则只需确定列表的哪一端将被视为堆栈的顶部,而哪一端将作为低端。 之后就可以使用列表方法(例如append和pop)来实现操作。

#stack 选择尾端作为先读取的地方

class Stack:

def __init__(self):

self.items = []

def is_empty(self):

return self.items == []

def push(self,item):

return self.items.append(item) #尾端添加

def peek(self):

return self.items[len(self.items)-1]

def pop(self):

return self.items.pop()

def size(self):

return len(self.items)

(注意item代码的单复数)

注意:我们可以选择列表来实现堆栈,其中顶部在开头而不是结尾。在这种情况下,先前的pop和append方法将不再起作用,我们将使用pop和insert显式索引位置0(列表中的第一项)

#stack 选择首端作为先读取的地方

class Stack:

def __init__(self):

self.items = []

def is_empty(self):

return self.items == []

def push(self,item):

return self.items.insert(0,item) #顶端添加

def peek(self):

return self.items[0]

def pop(self):

return self.items.pop(0)

def size(self):

return len(self.items)

这两种实现的性能存在差异。append和pop()操作都是 (1),意味着无论堆栈上有多少个项目,第一个实现都将在恒定时间内执行推入和弹出操作。第二种实现的性能,因为insert(0)和pop(0)操作都将需要 ( )来生成大小为的堆栈。即使在逻辑上是等效的,但执行基准测试时的计时有很大不同。

平衡的括号表示每个开始符号都有一个对应的结束符号,并且括号正确嵌套。 以下平衡的括号字符串:

(()()()())

(((())))

(()((())()))

不平衡的括号字符串:

((((((())

()))

(()()(()

参考图书 :Problem Solving with Algorithms and Data Structures, Release 3.0

其中有一段介绍stack来解决balanced parentheses的,放在这里大家看一下作者的陈述:

To solve this problem we need to make an important observation. As you process symbols from left to right, the most recent opening parenthesis must match the next closing symbol. Also, the first opening symbol processed may have to wait until the very last symbol for its match. Closing symbols match opening symbols in the reverse order of their appearance; they match from the inside out. This is a clue that stacks can be used to solve the problem.

Once you agree that a stack is the appropriate data structure for keeping the parentheses, the statement of the algorithm is straightforward. Starting with an empty stack, process the parenthesis strings from left to right. If a symbol is an opening parenthesis, push it on the stack as a signal that a corresponding closing symbol needs to appear later. If, on the other hand, a symbol is a closing parenthesis, pop the stack. As long as it is possible to pop the stack to match every closing symbol, the parentheses remain balanced. If at any time there is no opening symbol on the stack to match a closing symbol, the string is not balanced properly. At the end of the string, when all symbols have been processed, the stack should be empty.

1) the most recent opening parenthesis must match the next closing symbol

2)Closing symbols match opening symbols in the reverse order of their appearance

重点是左边符号与右边符号相匹配,而且要遵守前后顺序

Starting with an empty stack ----》

process the parenthesis strings from left to right----》

If a symbol is an opening parenthesis, push it on the stack as a signal that a corresponding closing symbol needs to appear later.

If, on the other hand, a symbol is a closing parenthesis, pop the stack. As long as it is possible to pop the stack to match every closing symbol, the parentheses remain balanced.

If at any time there is no opening symbol on the stack to match a closing symbol, the string is not balanced properly.

At the end of the string, when all symbols have been processed, the stack should be empty

解析:

def par_checker(symbol_string): #首先定义函数

s = Stack() #create a stack object 建立一个空的stack

is_balanced = True # 设定值为true,之后遇到false情况再设定为false

index = 0 # keep track where we are in the string that we are looping through 从左到右依次check

def is_match(p1,p2): # 设定一个新函数is_match,判断符号两边是否一致,这里考虑三种符号的情况

if p1 =='('and p2 ==')':

return True

elif p1 == '[' and p2 ==']':

return True

elif p1 == '{' and p2 =='}':

return True

else:

return False

while index < len(symbol_string) and is_balanced : # string不为空

paren = symbol_string[index]

if paren in '([{': # 开始的符号为左边符号

s.push(paren) #添加到stack里面

else:

if s.is_empty(): #如果刚开始为右边符号,则不平衡

is_balanced = False

else:

top = s.pop() #如果左边符号已经添加完毕,现在开始pop右边符号

if not is_match(top,paren): #如果考察的符号与stack里已有的符号不相符(注意这里的顺序),则符号不平衡

is_balanced = False

index += 1 #依次考察每一个index

if s.is_empty() and is_balanced: #考察完毕如果stack为空则为符号平衡

return True

else:

return False

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值