還記得有一次筆試題,有一道括號匹配的算法題,當時沒有學習數據結構和算法,思路很模糊,后來了解一些數據結構之后就有思路了,今天將解法寫出來。
問題描述:
給定一個字符串,里邊可能包含“()”、"{}"、“[]”三種括號,請編寫程序檢查該字符串的括號是否成對出現。
輸出:
true:代表括號成對出現并且嵌套正確,或字符串無括號字符。
false:未正確使用括號字符。
1、分析
如果了解數據結構,那么應該知道,簡單的采用一個棧的特性,就能解決該問題,左括號棧頂字符必須和第一個入棧的右括號字符匹配。
棧介紹:棧是一種特殊的線性表,僅能在線性表的一端操作,棧頂允許操作,棧底不允許操作。
棧的特性:后進先出(LIFO)
棧示意
下面用一幅流程圖來說明程序運行步驟:
步驟流程圖
2、代碼實現
2.1 Python實現
使用list來代替棧實現相同的操作。聲明了幾個變量:
- BRANKETS:由配對的括號組成的字典,注意使用右括號作為key,因為我們要判斷的是右括號是否與左括號匹配,在字典中找出與key對應的value簡單,要是找value對應的key要復雜一些。
- BRANKETS_LEFT與BRANKETS_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類型的變量bracketLeft和bracketRight來存儲左括號和右括號,判斷右括號與左括號匹配的方法是:先在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
本文通過棧數據結構實現了括號匹配的判斷,希望讀者通過本文加深對棧的理解,并記住思路,沒準下次面試時就會碰到這道題。