哨兵。这个哨兵十分有用,专门针对因左右符号个数不同而引起的不匹配。在没有哨兵的状况下:
- 如果左括号多于右括号,则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;}