利用堆栈进行四则运算

来源:互联网 发布:小猪cms源码2017 编辑:程序博客网 时间:2024/03/29 18:54

       我们正常的四则运算在计算机里是并不被识别的,因此想要利用程序实现四则运算就需要先将我们熟悉的中缀表达式转化为无需括号的后缀表达式。这个后缀表达式是由波兰的逻辑学家JAN提出,也称为逆波兰式。


       利用堆栈转换后缀表达式:

       中缀表达式:9+((10-2)*3+3*3)*4+10/2 转化为后缀表达式:9 10 2 - 3 * 3 3 * + 4 * + 10 2 / +

规则:从左到右遍历中缀表达式的每一个数字和符号,若是数字就输出,即成为后缀表达式的一部分;若是符号则先判断是否是右括号如若是右括号则输出栈顶到左括号间的所有符号成为后缀表达式一部分,如若不是则再判断其与栈顶符号的运算优先级,输出从栈顶高优先级到第一个低于当前符号优先级(或者左括号)这之间所有符号并将当前符号入栈,一直到最终输出后缀表达式为止。

       后缀表达式的计算:

规则:从左到右遍历后缀表达式的每个数字和符号,遇到数字就进栈,遇到符号就将处于栈顶两个数字出栈,进行运算(如果是减被减数是第二个数)运算结果进栈,最后结果就在栈里直接输出就可以。


下面是完整的代码:

#include<Windows.h>#include<iostream>#include <string>#include <vector>using namespace std;struct sqstack{char c[20][10];int top;};void InitStack(sqstack*s){s->top=-1;for(int i=0;i<20;i++)for (int j=0;j<10;j++) s->c[i][j]='\0';}BOOL Push(sqstack*s,char e[10]){if (s->top==19)return FALSE;s->top++;for (int i=0;i<10;i++)s->c[s->top][i]=e[i];return TRUE;}BOOL Pop(sqstack*s,char e[10]){if (s->top==-1)return FALSE;for (int i=0;i<10;i++)e[i]=s->c[s->top][i];s->top--;return TRUE;}int MidSew(string s,char a[20][10]) //保存中缀表达式{int k=0,j=0,e=0;for (int i=0;i<s.size();i++){if((s[i]!='*')&&(s[i]!='/')&&(s[i]!='-')&&(s[i]!='+')&&(s[i]!='(')&&(s[i]!=')'))k++;else{if (k!=0){for ( j=i-k;j<i;j++)a[e][j-i+k]=s[j];for (int jjj=k;jjj<10-k;jjj++)a[e][j]='\0';e++;k=0;}a[e][0]=s[i];e++;}if (i==(s.size()-1)&&k!=0){for ( j=i-k+1;j<=i;j++)a[e][j-i+k-1]=s[j];for (int jj=k;jj<10-k;jj++)a[e][k]='\0';e++;  k=0;}}return e;//中缀表达式最终字符数}int BehindSew(char a[20][10],char behd[20][10],int e) //获取后缀表达式{sqstack stk;InitStack(&stk);char mid[10];int pp=0;for (int p=0;p<e;p++){if ((a[p][0]!='*')&&(a[p][0]!='/')&&(a[p][0]!='-')&&(a[p][0]!='+')&&(a[p][0]!='(')&&(a[p][0]!=')')){for (int i=0;i<10;i++){behd[pp][i]=a[p][i];}pp++;}else{if (a[p][0]=='(')Push(&stk,a[p]);if (a[p][0]==')'){while (stk.top!=-1){if (stk.c[stk.top][0]!='('){Pop(&stk,behd[pp]);pp++;}else{Pop(&stk,mid);break;}}}if ((a[p][0]=='+')||(a[p][0]=='-')){while (stk.top!=-1){if (stk.c[stk.top][0]!='('){Pop(&stk,behd[pp]);pp++;}elsebreak;}Push(&stk,a[p]);}if ((a[p][0]=='*')||(a[p][0]=='/')){Push(&stk,a[p]);}}}while (stk.top!=-1){Pop(&stk,behd[pp]);pp++;    //最终实际后缀表达式字符数}return pp;}int ResultCount(int pp,char behd[20][10]) //计算结果{char mid[10];//中间过渡sqstack stk;InitStack(&stk);for (int u=0;u<pp;u++){if ((behd[u][0]!='*')&&(behd[u][0]!='/')&&(behd[u][0]!='-')&&(behd[u][0]!='+')&&(behd[u][0]!='(')&&(behd[u][0]!=')')){Push(&stk,behd[u]);}else{int x=0,y=0;Pop(&stk,mid);x=atoi(mid);Pop(&stk,mid);y=atoi(mid);switch(behd[u][0]){case '-':x=y-x;break;case'+':x=x+y;break;case '*':x=x*y;break;case'/':x=y/x;break;}itoa(x,mid,10);Push(&stk,mid);}}Pop(&stk,mid);return atoi(mid);}void OutExpression(char behd[20][10],int pp){ for (int y=0;y<pp;y++) { if ((behd[y][0]!='*')&&(behd[y][0]!='/')&&(behd[y][0]!='-')&&(behd[y][0]!='+')&&(behd[y][0]!='(')&&(behd[y][0]!=')')) cout<<atoi(behd[y])<<" "; else cout<<behd[y][0]<<" "; }}int main(){string s;cout<<"请输入正确的四则表达式(支持+-*/以及小括号):";cin>>s;char a[20][10];char behd[20][10];char b[10];int c=MidSew(s,a);c=BehindSew(a,behd,c);cout<<endl<<"后缀表达式为:";OutExpression(behd,c);cout<<endl<<endl<<"计算结果为:"<<ResultCount(c,behd);Sleep(100000);


0 0
原创粉丝点击