表达式的转换
表达式的转换
| Time Limit: 5000MS | Memory Limit: 65535KB |
| Submissions: 56 | Accepted: 19 |
Sample Input
8-(3+2*6)/5+4
Sample Output
8 3 2 6 * + 5 / - 4 + 8 3 12 + 5 / - 4 + 8 15 5 / - 4 + 8 3 - 4 + 5 4 + 9
分析:
求后缀式过程:
如果是'^'、'*'、'/'、'+'、'-'、'('、')',就与前一位运算符比较;看是进运算符栈,还是进后缀式;
如果是数字,就直接进入后缀式;
最后将没进后缀式的运算符压进后缀式
对后缀式求值过程:
先遍历后缀式,将数字都记录在数值栈中,遇到运算符就将前两位的数字弹出并进行运算,压入运算结果;
就这样不断循环就可得出结果
# include<stdio.h> # include<iostream> # include<malloc.h> # include<math.h> # define N 1000 using namespace std; char postexp[N];//后缀表达式 struct Node { char ch;//符号 int pri;//优先级 } lpri[8]={{'=',0},{'(',1},{'^',7},{'*',5},{'/',5},{'+',3},{'-',3},{')',8}}, rpri[8]={{'=',0},{'(',8},{'^',6},{'*',4},{'/',4},{'+',2},{'-',2},{')',1}}; typedef struct node1//运算符栈 { char data[N]; int top; }SeqStack; struct node2//数值栈 { int data[N]; int top; }st; int leftpri(char chr) { int i; for(i=0;i<8;i++) { if(lpri[i].ch==chr) return lpri[i].pri; } } int rightpri(char chr) { int i; for(i=0;i<8;i++) { if(rpri[i].ch==chr) return rpri[i].pri; } } int InOp(char chr)//确定是运算符 { if(chr=='('||chr==')'||chr=='+'||chr=='-'||chr=='*'||chr=='/'||chr=='^') return 1; else return 0; } int Precede(char chr1,char chr2)//确定优先级的大小 { int lsign=leftpri(chr1);//这样记录,就不用重复调用函数了 int rsign=rightpri(chr2); if(lsign==rsign) return 0; else if(lsign<rsign) return -1; else return 1; } int trans(char *exp) { SeqStack op; int i=0; op.top=-1; op.top++; op.data[op.top]='=';//为结束做标记,并且让第一位有所对比 while(*exp!='\0') { if(!InOp(*exp)) { while(*exp>='0'&&*exp<='9')//就本题而言,这里不用循环;但循环就可读入一位以上的数 { postexp[i++]=*exp; exp++; } postexp[i++]=' ';//空格在这里有两个用处,一可以隔开区别数字,二可以方便最后输出 } else { switch(Precede(op.data[op.top],*exp)) { case -1://如果进入的运算符优先级大于前一位的话,继续压入运算符栈 { op.top++; op.data[op.top]=*exp; exp++; } break; case 0://如果进入的运算符优先级等于前一位的话,弹出前一位运算符,这种情况只有是括号才行 { op.top--; exp++; } break; case 1://如果进入的运算符优先级小于前一位的话,弹出前一位运算符,进入后缀表达式 { postexp[i++]=op.data[op.top]; postexp[i++]=' '; op.top--; } break; } } } while(op.data[op.top]!='=')//将剩余的运算符压入后缀表达式 { postexp[i++]=op.data[op.top]; postexp[i++]=' '; op.top--; } postexp[i]='\0'; return i;//返回后缀表达式的长度 } int solve(int num1,int num2,char ch) { switch(ch) { case '+':return num1+num2;break; case '-':return num1-num2;break; case '*':return num1*num2;break; case '/':return num1/num2;break; case '^':return (int)pow((double)num1,(double)num2);break; } } void compvalue(int len) { int j,num1,num2,d,cnt=0; st.top=-1; while(postexp[cnt]!='\0') { if(postexp[cnt]>='0'&&postexp[cnt]<='9') { d=0; while(postexp[cnt]!=' ')//将符号转换成数字 { d=10*d+postexp[cnt]-'0'; cnt++; } st.top++; st.data[st.top]=d;//进入数值栈 } else { num2=st.data[st.top]; st.top--; num1=st.data[st.top]; st.data[st.top]=solve(num1,num2,postexp[cnt]); for(j=0;j<=st.top-1;j++)//前一部分肯定是数字,就用数值栈就行 { printf("%d ",st.data[j]); } printf("%d",st.data[j]); for(j=cnt+1;j<len-1;j++)//接着将后缀式的后部分输出就行了 { printf("%c",postexp[j]); } printf("\n"); cnt++; } cnt++;//跳过空格 } } int main() { char exp[N]; int len,i; scanf("%s",exp); len=trans(exp);//求后缀式 for(i=0;i<len-1;i++) { printf("%c",postexp[i]); } printf("\n"); compvalue(len);//计算后缀式的值 return 0; }
浙公网安备 33010602011771号