【Python】(九)Python实现栈

作者: hitsunbo | 来源:发表于2017-02-23 15:48 被阅读117次

与队列一样,我们以列表为基础实现栈。
这里,我们将列表的最后一个元素作为栈顶。
栈的结构和功能都很简单,实现并不复杂,代码如下:

class Stack(object):
    # Stack() 创建一个空的新栈。
    def __init__(self):
        self.items = []
    
    # push(new_item)将一个新的元素添加到栈顶。
    def push(self, new_item):
        self.items.append(new_item)
    
    # 返回栈顶元素,但不会弹出它。
    def top(self):
        return self.items[-1]
        
    # 弹出并返回栈顶元素
    def pop(self):
        return self.items.pop()
        
    # 返回栈是否为空。栈空返回true,否则返回false。
    def isEmpty(self):
        return [] == self.items
    
    # 返回栈的长度,即栈中元素的个数。
    def size(self):
        return len(self.items)

括号匹配问题

括号匹配问题是栈应用的入门级问题,虽然简单,但却很好的体现了栈在实际引用中的灵活性性和高效性。
以下是三个正确的括号匹配字符串:

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

以下是三个不正确的括号匹配字符串:

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

用栈解决这一问题的有效思路:
从空栈开始,从左到右遍历字符串。
如果一个符号是一个左括号,将其作为一个匹配需求入栈,其对应的右括号稍后应当会出现。
如果符号是右括号,弹出栈,只要弹出栈的左括号与该右括号相匹配。
最后,当所有符号都被处理后,栈应该是空的。

简单的实现代码如下:

class Stack(object):
    # Stack() 创建一个空的新栈。
    def __init__(self):
        self.items = []
    
    # push(new_item)将一个新的元素添加到栈顶。
    def push(self, new_item):
        self.items.append(new_item)
    
    # 返回栈顶元素,但不会弹出它。
    def top(self):
        return self.items[-1]
        
    # 弹出并返回栈顶元素
    def pop(self):
        return self.items.pop()
        
    # 返回栈是否为空。栈空返回true,否则返回false。
    def isEmpty(self):
        return [] == self.items
    
    # 返回栈的长度,即栈中元素的个数。
    def size(self):
        return len(self.items)

# 检查小括号的匹配是否正确。checking_string为传入的待检查的字符串。
def Parentheses_check(checking_string):
    stack = Stack() #创建一个新的栈用于保存未被匹配的左括号
    
    for checking_char in checking_string : #从左到右,逐个遍历字符串中的字符
        if checking_char == '(': #当前符号为左括号
            stack.push(checking_char) #将左括号这一匹配需求入栈
        else : #当前符号为右括号
            if stack.isEmpty(): #栈中的已没有匹配需求,返回匹配失败,字符串有误
                return False
            else: #栈中有匹配需求,弹出这个需求进行匹配
                stack.pop()
    
    if stack.isEmpty(): # 遍历过后所有匹配需求都被满足,则返回true
        return True
    else: #遍历后依然存在没被满足的匹配需求,则返回false
        return False
        
def main():
    string_list = ['(()()()())','(((())))','(()((())()))','((((((())','()))','(()()(()']
    for checking_string in string_list:
        print("%s ---- %s"%( Parentheses_check(checking_string), checking_string))
        print("-----------------")

if __name__ == "__main__":
    main()

运行结果如下:

True ---- (()()()())
-----------------
True ---- (((())))
-----------------
True ---- (()((())()))
-----------------
False ---- ((((((())
-----------------
False ---- ()))
-----------------
False ---- (()()(()
-----------------

结果是正确的。

多种括号的匹配问题

之前所做的任务仅包含小括号的匹配,但事实上,这种算法也可以很轻松的推广到多种符号的匹配上。例如,以下三个字符串可以正确的匹配:

{ { ( [ ] [ ] ) } ( ) }
[ [ { { ( ( ) ) } } ] ]
[ ] [ ] [ ] ( ) { }

以下三个字符串不能正确的匹配:

( [ ) ]
( ( ( ) ] ) )
[ { ( ) ]

基于同样的思路,只需要对“匹配”这一操作做下扩展,便可以解决多括号匹配的问题。
简单的代码实现如下:

class Stack(object):
    # Stack() 创建一个空的新栈。
    def __init__(self):
        self.items = []
    
    # push(new_item)将一个新的元素添加到栈顶。
    def push(self, new_item):
        self.items.append(new_item)
    
    # 返回栈顶元素,但不会弹出它。
    def top(self):
        return self.items[-1]
        
    # 弹出并返回栈顶元素
    def pop(self):
        return self.items.pop()
        
    # 返回栈是否为空。栈空返回true,否则返回false。
    def isEmpty(self):
        return [] == self.items
    
    # 返回栈的长度,即栈中元素的个数。
    def size(self):
        return len(self.items)
    
# 检查多种括号的匹配是否正确。
# checking_string为传入的待检查的字符串。
# left_list和right_list分别为左侧符号列表和右侧符号列表,两列表在索引上一一对应。
def Multi_parentheses_check(checking_string, left_list, right_list):
    
    stack = Stack() #创建一个新的栈用于保存未被匹配的左括号
    
    for checking_char in checking_string : #从左到右,逐个遍历字符串中的字符
        if checking_char in left_list: #当前符号为左括号
            stack.push(checking_char) #将左括号这一匹配需求入栈
        else : #当前符号为右括号
            if stack.isEmpty(): #栈中的已没有匹配需求,返回匹配失败,字符串有误
                return False
            else: #栈中有匹配需求,弹出这个需求进行匹配
                need_match = stack.pop()
                if left_list.index(need_match) != right_list.index(checking_char):  #索引相同,意味着匹配通过,否则匹配失败
                    return False
                    
    
    if stack.isEmpty(): # 遍历过后所有匹配需求都被满足,则返回true
        return True
    else: #遍历后依然存在没被满足的匹配需求,则返回false
        return False
        
def main():
    left_list  = ['(','[','{']
    right_list = [')',']','}']
    string_list = ['{{([][])}()}','[[{{(())}}]]','[][][](){}','([)]','((()]))','[{()]']
    for checking_string in string_list:
        print("%s ---- %s"%( Multi_parentheses_check(checking_string,left_list,right_list), checking_string))
        print("-----------------")

if __name__ == "__main__":
    main()

运行结果如下:

True ---- {{([][])}()}
-----------------
True ---- [[{{(())}}]]
-----------------
True ---- [][][](){}
-----------------
False ---- ([)]
-----------------
False ---- ((()]))
-----------------
False ---- [{()]
-----------------

结果也是正确的。
通过对匹配功能的修改,可以实现更复杂的一对一匹配。

相关文章

网友评论

    本文标题:【Python】(九)Python实现栈

    本文链接:https://www.haomeiwen.com/subject/ytqbwttx.html