使用Python實現一個棧, 判斷括號是否平衡

soong發表於2018-08-21

棧(Stack)在計算機領域是一個被廣泛應用的集合,棧是線性集合,訪問都嚴格地限制在一段,叫做頂(top)。 舉個例子,棧就想一摞洗乾淨的盤子,你每次取一個新盤子,都是放在這一摞盤子的最上頭,當你往裡面新增盤子的時候,也是放在最上面,處在底部的盤子,你可能永遠也用不到。 棧的最常見操作,有如下兩個:

push(a) # 壓入,將a壓入的棧中
pop() # 彈出,將棧的最後一個元素彈出
複製程式碼

可是使用Python的列表資料結構,來模擬棧的操作,使用append來模擬push,使用列表的pop來模擬棧的pop,但是這樣做有一個弊端,那就是列表原本自帶的操作方法同樣能夠使用,可能會造成混亂。

  • 棧的實現 下面就通過藉助Python的列表,來自定義一個棧類:
class Stack(object):
    """使用陣列實現一個棧"""
    def __init__(self):
        self.data = []

    def push(self, num):
        """壓棧操作"""
        self.data.append(num)

    def pop(self):
        """返回從棧中彈出的元素, 當棧為空的時候, 丟擲IndexError"""
        return self.data.pop()

    def peek(self):
        """檢視當前棧頂的元素, 當棧為空的時候, 丟擲IndexError"""
        return self.data[-1]

    def __len__(self):
        """返回棧的長度, 呼叫len(obj)時會自動呼叫obj物件的__len__方法"""
        return len(self.data)

    def isEmpty(self):
        """判斷棧是否為空"""
        return True if len(self.data)==0 else False

    def clear(self):
        """清空棧"""
        self.data = []

    def __repr__(self):
        """當前物件的表現形式, 在終點直接鍵入物件時會呼叫"""
        return 'Stack_' + str(self.data)

    def __str__(self):
        """當前物件的字串表示, 使用print(obj)時會呼叫"""
        return 'Stack_' + str(self.data)
複製程式碼

以上程式碼實現了一個簡單的基於列表的棧。

  • 棧的應用 棧應用的一個很典型的例子,就是檢查括號是否匹配。 例如: 每一個開始的[後面,都應該跟著一個位置正確的],並且每一個(後面,也應該跟著一個位置正確的結束的).
  1. (...)...(...)匹配
  2. (...)...(...不匹配
  3. )...((...)不匹配 像第三個示例中,雖然左右括號的數量是相等的,但是也是不匹配的,所以不能通過簡單的檢查數量來實現括號的檢測。 一種非常有效的解決方式就是使用棧:
  4. 掃描整個字串, 如果遇到一個開始的括號,將它壓入到棧中
  5. 如果遇到一個結束的括號,檢查棧頂的元素,如果是結束的括號,就將當前括號壓入棧中,如果是開始的括號,檢查與當前括號是否能配對,不能配對則不匹配
  6. 如果遇到一個結束的括號,並且當前棧為空的話,那麼也是不匹配的。 程式碼實現如下:
def isBalance(text):
    """棧的應用,檢查括號是否平衡"""
    result_stack = Stack()
    for i in text:
        if i in ['{', '[', '(']:
            result_stack.push(i)
        elif i in ['}', ']', ')']:
            # 遇到結束括號的情況
            if result_stack.isEmpty():
                # 如果當前棧為空, 不匹配,返回False
                return False
            chFromStack = result_stack.pop()
            
            if not ((chFromStack == '{' and i == '}' )
                    or (chFromStack == '[' and i == ']')
                    or (chFromStack == '(' and i == ')')):
                # 如果不滿足匹配條件, 則返回False
                return False

    # 遍歷結束後, 如果結果棧為空, 則代表括號匹配, 棧不為空, 括號不匹配
    return result_stack.isEmpty()

複製程式碼

相關文章