question link:hihocoder#1110
这题是一个简化版的正则表达式判错。主要用栈来实现,利用向左结合性,进行如下处理:
1.若左边已有合法表达式,栈顶用‘#’表示。
2.遇到 * ,检查栈顶。
3.遇到 | ,检查栈顶,然后push( | ).
4.遇到 ( ,push( ( ),并维护一个cnt记录左括号数量。
5.遇到 ),检查左括号是否匹配,若栈顶为左括号,直接pop;否则说明括号内有合法表达式,pop到左括号,并push(#)。
这题有个小trick可以避免频繁检查stack是否为空,方法是在初始化stack时push进一个与本题不相关的字符。
好了,上代码。
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int judge(string s){
stack<char> st;
int cnt=0;
st.push('^');
for (int i = 0; i < s.size(); i++){
if (s[i] == '('){
st.push(s[i]); cnt++;
}
else if (s[i] == ')'){
if (cnt == 0 || st.top() != '#')
{
if (st.top() == '(')st.pop();
else return 0;
}
else{
while (st.top() != '(') st.pop();
st.pop();
st.push('#');
}
cnt--;
}
else if (s[i] == '*'){
if (st.top() != '#')return 0;
}
else if (s[i] == '|'){
if (st.top() != '#')return 0;
st.push('|');
}
else if (s[i] = '0' || s[i] == '1'){
if (st.top() != '#')st.push('#');
}
else return 0;
}
if ((st.top() != '#'&&st.top()!='^') || cnt != 0)return 0;
return 1;
}
int main(){
ios::sync_with_stdio(false);
string s;
int c = 0;
while (cin >> s){
if(judge(s))cout<<"yes"<<endl;
else cout << "no" << endl;
}
return 0;
}