算法:括號匹配問題

還記得有一次筆試題,有一道括號匹配的算法題,當時沒有學習數據結構和算法,思路很模糊,后來了解一些數據結構之后就有思路了,今天將解法寫出來。

問題描述

給定一個字符串,里邊可能包含“()”、"{}"、“[]”三種括號,請編寫程序檢查該字符串的括號是否成對出現。

輸出:

true:代表括號成對出現并且嵌套正確,或字符串無括號字符。

false:未正確使用括號字符。

1、分析

如果了解數據結構,那么應該知道,簡單的采用一個棧的特性,就能解決該問題,左括號棧頂字符必須和第一個入棧的右括號字符匹配。

棧介紹:棧是一種特殊的線性表,僅能在線性表的一端操作,棧頂允許操作,棧底不允許操作。
棧的特性:后進先出(LIFO)

棧示意

下面用一幅流程圖來說明程序運行步驟:

步驟流程圖

2、代碼實現

2.1 Python實現

使用list來代替棧實現相同的操作。聲明了幾個變量:

  • BRANKETS:由配對的括號組成的字典,注意使用右括號作為key,因為我們要判斷的是右括號是否與左括號匹配,在字典中找出與key對應的value簡單,要是找value對應的key要復雜一些。
  • BRANKETS_LEFTBRANKETS_RIGHT分別存放左括號與右括號,用來判斷字符屬于哪個陣營。
#-*- coding: utf-8 -*-

BRANKETS = {'}':'{',']':'[',')':'('}
BRANKETS_LEFT, BRANKETS_RIGHT = BRANKETS.values(), BRANKETS.keys()

def bracket_check(string):
    """括號匹配檢測函數"""
    stack = []
    for char in string:
        # 如果是左括號
        if char in BRANKETS_LEFT:
            # 入棧
            stack.append(char)
        # 右括號
        elif char in BRANKETS_RIGHT:
            # stack不為空,并且括號匹配成功
            if stack and stack[-1] == BRANKETS[char]:
                # 出棧
                stack.pop()
            # 匹配成功
            else:
                return False
    
    return not stack

def main():
    print(bracket_check('{brace*&^[square(round)]end}'))
    print(bracket_check('{brace*&^[square(round])end}'))

if __name__ == '__main__':
    main()

輸出結果:

true
false

2.2 C++實現

C++中自帶棧數據結構,需要包含頭文件<stack>。使用string類型的變量bracketLeftbracketRight來存儲左括號和右括號,判斷右括號與左括號匹配的方法是:先在bracketRight找到該字符的索引,然后對比棧頂字符和bracketLeft相同索引處的字符是否匹配。

#include <stack>
#include <iostream>

using namespace std;

string bracketLeft = "{[(";
string bracketRight = "}])";

bool BracketCheck(string str)
{
    stack<char> s;
    // 遍歷字符串
    for (int i = 0; i < str.length(); i++)
    {
        char chr = str[i];
        int indexLeft = -1, indexRight = -1;
        indexLeft = bracketLeft.find(chr);
        indexRight = bracketRight.find(chr);
        // 是左括號
        if (indexLeft >= 0)
            s.push(chr);    // 入棧
        // 是右括號
        else if (indexRight >= 0)
        {
            // 匹配成功
            if (!s.empty() && s.top() == bracketLeft[indexRight])
                s.pop();    // 出棧
            else
                return false;
        }
    }

    return s.empty();
}

int main()
{
    cout << boolalpha << BracketCheck("{brace*&^[square(round)]end}") << endl;
    cout << boolalpha << BracketCheck("{brace*&^[square(round])end}") << endl;
    return 0;
}

輸出結果:

true
false

本文通過數據結構實現了括號匹配的判斷,希望讀者通過本文加深對的理解,并記住思路,沒準下次面試時就會碰到這道題。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容