其实也不算原创,综合了一下网上神牛题解的思路与实现技巧。
先说题意:
给你一些宏定义,判断最后的式子是否能正确表达原来的意思
这是一个表达式求解的题
不正确表达无非就是前后两个符号会通过
改变运算顺序而错误表达原来的意思
如 a- (B+C) 无括号就会表达错误
首先可以给表达式分类,来简化我们的判断
1.无论如何都是正确的
一个纯单词或括号非错式子
2.错误的
3.在前面加上 “-” ,或挨着“*” “/”就会错的(如"a+b")
4.在前面加上“/” ,就会错的
,挨着“*”或“-”不会错(如“a/b““a*b”)
只有这四种
那么每次以一个运算符c为中心,若可以将表达式s分成左右两块独立的表达式a和b:
如果a或b是错的,s也是错的,为2。
否则:
如果c为“+”,那么s为3。
如果c为“-”,b为3时s为2,否则为3。
。。。。。。
这样。
可这个程序如何实现呢?
我们用三个参数
s,l,r
分别表示表达式,目前正在计算的左端点,右端点。
返回值为(s,l,r)是哪一类
目标,算出s,0,len(s)-1是哪一类
1.先说最简单的,一个纯单词,先看他有没有define的意义,有就递归去搜,否则
(s,l,r)=1
;
2.s是由括号括起来的时,(s,l,r)=(s,l+1,r-1);
3.s中有四则运算,找出最后一个使用的运算符(有+-就是+-,否则是*/)
因为最后一个运算符运算时前面的运算都用过了,那么这个运算双方就为前面和后面,
直接分成两半递归调用。
否则,如a/b*c
最后一个为*
如果先分析/,无法找出除数究竟是b还是b*c(要找的话会复杂)
但如果先分析*,一定是c和a/b。
+-也如此
那么程序设计的思路就很清晰了
先特判1.2
再找最后一个计算的运算符(有+-就是+-,否则是*/)
再以运算符为中心分成两半递归处理,四种状态互相转移
思路清晰,码代码就快:
另外,输入很恶心,多看几个题解吧
AC代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<map>
#include<string>
#include<iostream>
#define maxn 105
using namespace std;
int n;
map<string,int>M,F;
char s[maxn],c[maxn][maxn],tmp[maxn],na[maxn][maxn],st[maxn];
int cnt[maxn],len[maxn];
int ser(string s,int l,int r){
int op=0,kuo=0,a,b;
string ss;
for(int i=r;i>=l;i--){
if(s[i]=='(')
kuo++;
if(s[i]==')')
kuo--;
if((s[i]=='*' || s[i]=='/') && kuo==0 && op==0) op=i;
if((s[i]=='+' || s[i]=='-') && kuo==0){
a=ser(s,l,i-1);
b=ser(s,i+1,r);
if(a==2 || b==2) return 2;
if(s[i]=='+') return 3;
if(s[i]=='-')
{
if(b==3) return 2;
return 3;
}
}
}
if(op){
a=ser(s,l,op-1);
b=ser(s,op+1,r);
if(a==2 || b==2) return 2;
if(s[op]=='*'){
if(a==3 || b==3) return 2;
return 4;
}
else{
if(b==3 || b==4 || a==3) return 2;
return 4;
}
}
if(s[r]==')' && s[l]=='('){
if(ser(s,l+1,r-1)==2) return 2;
return 1;
}
else{
ss="";
for(int i=l;i<=r;i++)
ss+=s[i];
if(M[ss]) return M[ss];
return 1;
}
}
int main(){
char ANS[2][15]={"OK","Suspicious"};
string s2,s,s3;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>s;
cin>>s;
if(s=="define")cin>>s;
getline(cin,s2);
s3="";
for(int j=0;j<s2.length();j++)
if(s2[j]!=' ')
s3+=s2[j];
M[s]=ser(s3,0,s3.length()-1);
}
getline(cin,s2);
s3="";
for(int j=0;j<s2.length();j++)
if(s2[j]!=' ')
s3+=s2[j];
printf("%s\n",ANS[ser(s3,0,s3.length()-1)==2]);
}