中缀表达式值
中缀表达式值(Expr.cpp)
【问题描述】
输入一个中缀表达式(由0-9组成的运算数、加+减—乘*除/四种运算符、左右小括号组成。注意“—”也可作为负数的标志,表达式以“@”作为结束符),判断表达式是否合法,如果不合法,请输出“NO”;否则请把表达式转换成后缀形式,再求出后缀表达式的值并输出。
注意:必须用栈操作,不能直接输出表达式的值。如果再考虑是实数运算呢?
【输入文件】Expr.in
输入文件的第一行为一个以@结束的字符串。
【输出文件】Expr.out
如果表达式不合法,请输出“NO”,要求大写。
如果表达式合法,请输出计算结果。
【输入样例】
1+2×8―9
【输出样例】
8
‘
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 using namespace std; 6 int number[101],i=0, p=1; 7 char symbol[101],s[256],t[256]; 8 void push() //算符入栈运算 9 { 10 symbol[++p]=s[i]; 11 } 12 void pop() //运算符栈顶元素出栈,并取出操作数栈元素完成相应的运算 13 { 14 switch (symbol[p--])//运算完成之后扔掉运算符,也标志着需要运算的数已经运算完成 15 { 16 case '+': 17 { 18 number[p]+=number[p + 1]; 19 break; 20 } 21 case '-': 22 { 23 number[p]-=number[p + 1]; 24 break; 25 } 26 case '*': 27 { 28 number[p]*=number[p + 1]; 29 break; 30 } 31 case '/': 32 { 33 number[p]/=number[p + 1]; 34 break; 35 } 36 case '^': 37 { 38 number[p]=pow(number[p],number[p + 1]); 39 } 40 } 41 } 42 bool can() //判断运算符的优先级别,建立标志函数,能否进行运算 43 { 44 if ((s[i]=='+'||s[i]=='-')&&symbol[p]!='(') //在括号之内 45 return 1; 46 if ((s[i]=='*'||s[i]=='/')&&(symbol[p]=='*'||symbol[p]=='/')) 47 //若遇到乘除且p对应的恰好是乘除 48 return 1; 49 return 0; 50 } 51 bool judge(char s[256]) 52 { 53 int top=0,i=0; 54 while (s[i]!='@') 55 { 56 if (s[i]=='(') top++; 57 if (s[i]==')') 58 { 59 if (top>0) top--; 60 else return 0; 61 } 62 i++; 63 } 64 if (top!=0) return 0; //检测栈是否为空。不空则说明有未匹配的括号 65 else return 1; 66 } 67 int main() 68 { 69 gets(s); 70 if(judge(s)==0) 71 { 72 cout<<"NO"; 73 return 0; 74 } 75 76 s[strlen(s)]=')'; 77 symbol[p]='('; 78 while (i<strlen(s)) 79 { 80 while (s[i]=='(') //左括号处理,压入左括号,有了左括号才能进行与右括号的匹配 while (symbol[p]!='(') 81 { 82 push(); 83 i++; 84 } 85 int x=0; 86 while (s[i]>='0'&&s[i]<='9') //取数入操作数栈 87 x=x*10+s[i++]-'0'; 88 number[p]=x; 89 do 90 { 91 if (s[i]==')') //当右括号后面还有右括号时处理 92 { 93 while (symbol[p]!='(') 94 pop();//当括号内还有算式没有算完时进行运算 95 number[--p]=number[p + 1];//当运算完成以后左括号已经没有意义,所以将指针p移向前一个运算符,并复制所得的结果 96 } 97 else 98 { //根据标志函数值作运算符入栈或出栈运算处理 99 while (can()) 100 pop();// 当可以进行运算时运算,然后压入一个运算符 101 push(); 102 } 103 i++; 104 }while (i<strlen(s)&&s[i-1]==')');//当检测到右括号时,可以运算括号内的内容 105 } 106 printf("Result=%d", number[0]);//因为所有的运算全部是建立在括号之内的,所以随着运算符的减少(运算符减少同时标志着需要操作的数减少)和最后的p--,结果一定保存在number[0]内 107 return 0; 108 }
作者:自为风月马前卒
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。