哨兵。这个哨兵非常有用,专门针对因左右符号个数不同而引起的不匹配。在没有哨兵的情况下:
- 如果左括号多于右括号,则for循环结束后栈中仍有符号,不为空,程序会给出已匹配的结果。但实质上这是不匹配的。如果用上这个#,则判断循环结束后栈顶元素是否为#就可以,如果是#,说明真的已经完全匹配;如果不是#,则肯定是错的。
- 如果右括号多于左括号。则在for循环程序中会直接崩溃,因为命名栈已经空了,却还要再取栈顶元素去判断,显然是无法取得,会使程序崩溃。如果用上这个#,则当取到#时,实质上就已经不匹配了,因为至少少一个左括号。在程序流程中也不会崩溃,因为当取到得是#时,"if"和"else if"语句都不满足,直接掉到"else"语句中,给出不匹配的说明,然后退出程序。
#include <iostream>
#include <stack>
#include <string.h>
#include <cstdio>
using namespace std;
string str;
bool isValid()
{
stack<char> s;
s.push('#'); //哨兵
int len = str.length();
for (int i = 0; i < len; i++)
{
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
s.push(str[i]);
else if ((str[i] == ')' && s.top() == '(') || (str[i] == ']' && s.top() == '[') | (str[i] == '}' && s.top() == '{'))
s.pop();
//这个else if是用来支持 “hello((({as})))world” 这种测试样例的
/*
else if(str[i]!='(' && str[i]!='[' && str[i]!='{' && str[i]!=')' && str[i]!=']' && str[i]!='}')
{
continue;
}
*/
else
return false;
}
if (s.top() == '#')
return true;
return false;
}
int main()
{
// freopen("c.txt","r",stdin);
getline(cin, str);
if (isValid())
cout << "成功";
else
cout << "失败";
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。