java利用栈求复杂表达式_利用栈进行表达式求解

以前A掉的表达式求解统统是递归= =,栈一直不知道怎么搞,今天稍微看了看,写了一个较简单的。

对于一个合法的表达式,只要知道运算符的优先级即可利用栈求解,貌似是将中缀表达式转化为了后缀表达式,这些个名词咳咳= =

顾名思义后缀表达式就是运算符写在后面嘛,对于a+b就是ab+ ,我们就知道要计算ab的和,对于一些更复杂状态的式子,显然需要一些技巧。

注意到这个题目中只有Smax一个函数所以可以用逗号来替代这个函数更加简便,我们用两个栈保存中间变量,一个储存符号的栈sc,一个储存中间值的栈si,还要有一个优先级表。

当前字符如果是一个数字那就计算出连续的这个数字并加入到si中,如果是个字符的话,与sc栈顶字符比较优先级,如果等于栈顶那就出栈(对于'(',')'这些特殊的匹配符号),如果大于栈顶那么说明应该先执行这个运算符,

入栈即可,如果小于栈顶,说明我们要用掉栈顶的运算符,取出si中的两个数后根据栈顶符号计算后再将结果加入到si中,注意到可能有多个需要计算的运算符所以这里用一个循环表达。为了方便引入'#'这个匹配字符,这样不用判断栈空的情况,显然最后sc中只有一个数字,就是答案了。

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 using namespacestd;10 #define inf 0x3f3f3f3f

11 char opt[]={'=',',','*','(',')','#'};12 int g[10][10]={13 {1,1,-1,-1,1,1},14 {-1,1,-1,-1,1,1},15 {1,1,1,-1,1,1},16 {-1,-1,-1,-1,0,1},17 {1,1,1,0,1,1},18 {-1,-1,-1,-1,-1,0}19 };20 mapM;21 char s[330];22 stacksc;23 stacksi;24 int num(intN)25 {26 int r=0; while(N){r+=N%10;N/=10;}27 returnr;28 }29 int cal(int a,int b,charch)30 {31 switch(ch){32 case '+':return a+b;break;33 case '*':return a*b;break;34 case ',':return max(num(a),num(b));break;35 }36 }37 intmain()38 {39 intT,N,i,j,k;40 for(i=0;i<6;++i)41 M[opt[i]]=i;42 cin>>T;43 while(T--){44 scanf("%s",s);45 N=strlen(s);46 s[N]='#';47 while(!sc.empty())sc.pop();48 while(!si.empty())si.pop();49 sc.push('#');50 for(i=0;i<=N;++i)51 {52 int t=-1;53 if(isdigit(s[i])){54 t=s[i]-'0';55 while(isdigit(s[i+1])){56 t=t*10+s[++i]-'0';57 }58 si.push(t);59 }60 else{bool ok=1;61 while(ok){62 if(s[i]=='S')i+=4;63 int x=g[M[sc.top()]][M[s[i]]];64 if(x==0) ok=0,sc.pop();65 else if(x==-1) ok=0,sc.push(s[i]);66 else{67 int a1=si.top();si.pop();68 int a2=si.top();si.pop();69 si.push(cal(a2,a1,sc.top()));70 sc.pop();71 }72 }73 }74 }75 cout<

有了四种运算+-*/ , 其实和上面的类似改下代码就能AC,当然可以写的更简单,不过为了练习栈就这样写了。

1 #include

2 #include

3 #include

4 #include

5 #include

6 #include

7 #include

8 #include

9 using namespacestd;10 #define inf 0x3f3f3f3f

11 char opt[]={'+','-','*','/','(',')','#'};12 int g[10][10]={13 {1,1,-1,-1,-1,1,1},14 {1,1,-1,-1,-1,1,1},15 {1,1,1,1,-1,1,1},16 {1,1,1,1,-1,1,1},17 {-1,-1,-1,-1,-1,0,1},18 {1,1,1,1,0,1,1},19 {-1,-1,-1,-1,-1,-1,0}20 };21 mapM;22 char s[1005];23 stacksc;24 stacksi;25 double cal(double a,double b,charch)26 {27 switch(ch){28 case '+':return a+b;break;29 case '*':return a*b;break;30 case '-':return a-b;break;31 case '/':return a/b;break;32 }33 }34 intmain()35 {36 intT,N,i,j,k;37 for(i=0;i<7;++i)38 M[opt[i]]=i;39 while(gets(s)){40 N=strlen(s);41 if(N==1&&s[0]=='0') break;42 s[N]='#';43 while(!sc.empty())sc.pop();44 while(!si.empty())si.pop();45 sc.push('#');46 for(i=0;i<=N;++i)47 {48 if(s[i]==' ') continue;49 double t=-1;50 if(isdigit(s[i])){51 t=s[i]-'0';52 while(isdigit(s[i+1])){53 t=t*10+s[++i]-'0';54 }55 si.push(t);56 }57 else{bool ok=1;58 while(ok){59 int x=g[M[sc.top()]][M[s[i]]];60 if(x==0) ok=0,sc.pop();61 else if(x==-1) ok=0,sc.push(s[i]);62 else{63 double a1=si.top();si.pop();64 double a2=si.top();si.pop();65 si.push(cal(a2,a1,sc.top()));66 sc.pop();67 }68 }69 }70 }71 printf("%.2f\n",si.top());72 }73 return 0;74 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值