1. 程式人生 > >【演算法】使用棧檢查表示式的括號匹配

【演算法】使用棧檢查表示式的括號匹配

使用棧檢查表示式的括號匹配

給定一個表示式字串exp,編寫一個程式來檢查對和“{”,“}”,“(”,“)”,“[”,“]”的順序是否在exp中是正確的。 例如,程式應該為exp =“[()] {} {[()()]()}”列印為true,對於exp =“[(])”則為false。

演算法步驟

其實這種字串有一個特點,就是如果當前字串是“右邊”的括號型別,那麼它的前一個必定是與之匹配的括號。

  1. 宣告一個字串棧
  2. 遍歷表示式字串exp
  3. 如果當前字元是起始括號“(”,"{","["則將其入棧。
  4. 如果當前字元是起始括號“)”,"}","]",將棧頂彈出,如果匹配右邊的括號則繼續重複3和4步驟,否則表示式判斷不符合要求。
  5. 完成遍歷後,堆疊必須為空才證明字串表示式符合要求
stack<string> stk;
//做對映的map
unordered_map<string, string> theMap =
{
    { "{", "}" },
    { "(", ")" },
    { "[", "]" }
};
//是否是左邊的括號
bool isLeft(string sub)
{
    return theMap.find(sub) != theMap.end();
}
//是否是右邊的括號
bool isRight(string sub)
{
    return std::find_if
(theMap.begin(), theMap.end(), [sub](std::pair<string, string> pair) { return pair.second == sub; }) != theMap.end(); } //左邊的能否和右邊匹配 bool isMatch(string left, string right) { auto iter = theMap.find(left); if (iter == theMap.end()) //錯誤的輸入 { return false; }
return iter->second == right; } void clearStack() { while (!stk.empty()) { stk.pop(); } } bool checkStringIsBalanced(string exp) { for (int i = 0; i < exp.size(); ++i) { //挨個取出字元 string sub = exp.substr(i, 1); if (isLeft(sub)) { stk.push(sub); continue; } //佇列空了但是 sub不是右邊符號說明結束了 if (stk.empty()) { return false; } //匹配上了說明配對成功 //Tips:也可以使用switch來匹配,不過程式碼可擴充套件性較差 if (isMatch(stk.top(), sub)) { stk.pop(); } else { return false; } } return stk.empty(); } void testMy() { clearStack(); string exp1("{[()]}"); cout << checkStringIsBalanced(exp1) << endl; clearStack(); string exp2("{[()]"); cout << checkStringIsBalanced(exp2) << endl; clearStack(); string exp3("{[)]}"); cout << checkStringIsBalanced(exp3) << endl; clearStack(); string exp4("{[()]}[]"); cout << checkStringIsBalanced(exp4) << endl; }

結果顯示第一個和第四個可以正常匹配。