【演算法】使用棧檢查表示式的括號匹配
阿新 • • 發佈:2018-12-12
使用棧檢查表示式的括號匹配
給定一個表示式字串exp,編寫一個程式來檢查對和“{”,“}”,“(”,“)”,“[”,“]”的順序是否在exp中是正確的。 例如,程式應該為exp =“[()] {} {[()()]()}”列印為true,對於exp =“[(])”則為false。
演算法步驟
其實這種字串有一個特點,就是如果當前字串是“右邊”的括號型別,那麼它的前一個必定是與之匹配的括號。
- 宣告一個字串棧
- 遍歷表示式字串exp
- 如果當前字元是起始括號“(”,"{","["則將其入棧。
- 如果當前字元是起始括號“)”,"}","]",將棧頂彈出,如果匹配右邊的括號則繼續重複3和4步驟,否則表示式判斷不符合要求。
- 完成遍歷後,堆疊必須為空才證明字串表示式符合要求
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;
}
結果顯示第一個和第四個可以正常匹配。