栈------表达式求值
栈的应用---表达式求值
1.简单计算器
Problem Description
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
Input
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
Output
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
Sample Input
1 + 2 4 + 2 * 5 - 7 / 11 0
Sample Output
3.00 13.36
Source
#include <iostream> #include <stack> #include <string> #include <cstdio> using namespace std; stack<double> opnd; //运算对象栈 stack<char> optr; //运算符号栈 void f() //取栈顶元素运算 { double tmp; char key=optr.top(); optr.pop(); double x=opnd.top(); opnd.pop(); double y=opnd.top(); opnd.pop(); switch(key) { case '+': tmp=x+y; break; case '-': tmp=y-x; break; case '*': tmp=x*y; break; case '/': tmp=y/x; break; } opnd.push(tmp); } int main() { double a,ans=0; char t,b; while(scanf("%lf",&a)==1) { opnd.push(a); scanf("%c",&t); if(a==0&&t=='\n') //结束循环 break; while(scanf("%s %lf",&b,&a)==2) { char ch=getchar(); //读入数字后面的字符 while(1) { if(optr.empty()||((b=='*'||b=='/')&&(optr.top()=='+'||optr.top()=='-'))) { optr.push(b); //栈空或下一个运算符优先级更高,入栈 opnd.push(a); break; } else //否则取栈顶元素运算然后运算符入栈 f(); } if(ch=='\n') //输出结果 { while(!optr.empty()) { f(); } ans=opnd.top(); printf("%.2lf\n",ans); while(!opnd.empty()) //多组测试数据,清空栈 { opnd.pop(); } while(!optr.empty()) { optr.pop(); } break; } } } return 0; }
这题至少整了两天,一开始是为了练一练STL,熟悉熟悉应用的,然后发现数据结构教科书上P87的例题写错了,只能进行10以内的加减乘除运算,除法还没法保持精度,然后这题一开始敲的时候就是整体将表达式读入,再处理的,没有注意到题中的每个符号之间都有一个空格,这能很好的简化题目,否则就得考虑字符串转化为数字的处理,手动模拟数字乘位权值;(这里,题目也没给清楚表达式里数字的范围,= =有想到java的大数浮点型)。最后终于AC了。。。
2.POJ2106 Boolean Expressions
Description
The objective of the program you are going to produce is to evaluate boolean expressions as the one shown next:
Expression: ( V | V ) & F & ( F | V )
where V is for True, and F is for False. The expressions may include the following operators: ! for not , & for and, | for or , the use of parenthesis for operations grouping is also allowed.
To perform the evaluation of an expression, it will be considered the priority of the operators, the not having the highest, and the or the lowest. The program must yield V or F , as the result for each expression in the input file.
where V is for True, and F is for False. The expressions may include the following operators: ! for not , & for and, | for or , the use of parenthesis for operations grouping is also allowed.
To perform the evaluation of an expression, it will be considered the priority of the operators, the not having the highest, and the or the lowest. The program must yield V or F , as the result for each expression in the input file.
Input
The expressions are of a variable length, although will never exceed 100 symbols. Symbols may be separated by any number of spaces or no spaces at all, therefore, the total length of an expression, as a number of characters, is unknown.
The number of expressions in the input file is variable and will never be greater than 20. Each expression is presented in a new line, as shown below.
The number of expressions in the input file is variable and will never be greater than 20. Each expression is presented in a new line, as shown below.
Output
For each test expression, print "Expression " followed by its sequence number, ": ", and the resulting value of the corresponding test expression. Separate the output for consecutive test expressions with a new line.
Use the same format as that shown in the sample output shown below.
Use the same format as that shown in the sample output shown below.
Sample Input
( V | V ) & F & ( F| V) !V | V & V & !F & (F | V ) & (!F | F | !V & V) (F&F|V|!V&!F&!(F|F&V))
Sample Output
Expression 1: F Expression 2: V Expression 3: V
Source
#include <iostream> #include <stack> #include <string> #include <cstdio> using namespace std; int main() { string s; int kase=1; //freopen("Atext.in","r",stdin); while(getline(cin,s)){ int x,y,c; stack<int> val; stack<char> op; for(int i=0;i<s.size();i++){ switch(s[i]) { case '(': op.push(s[i]); break; case '!': //注意如:!!!F,一开始没处理好RE了; if(!op.empty()&&op.top()=='!'){ op.pop();//注意!为单目运算符,一开始没处理好! }else op.push(s[i]); break; case '|': case '&': case ')': while(!op.empty()){ if(op.top()=='!'){ x=val.top(); val.pop(); val.push((!x)); op.pop(); }else if(op.top()=='|') { x=val.top(); val.pop(); y=val.top(); val.pop(); val.push((x|y)); op.pop(); }else if(op.top()=='&') { x=val.top(); val.pop(); y=val.top(); val.pop(); val.push((x&y)); op.pop(); }else break; } if(s[i]==')') op.pop(); else op.push(s[i]); break; case 'V': val.push(1); break; case 'F': val.push(0); break; default : break; } } while(!op.empty()){ if(op.top()=='!'){ x=val.top(); val.pop(); val.push((!x)); op.pop(); }else if(op.top()=='|') { x=val.top(); val.pop(); y=val.top(); val.pop(); val.push((x|y)); op.pop(); }else if(op.top()=='&') { x=val.top(); val.pop(); y=val.top(); val.pop(); val.push((x&y)); op.pop(); } } // cout << val.size() << endl; //cout << op.size() << endl; printf("Expression %d: ",kase++); if(val.top()==1) printf("V\n"); else printf("F\n"); } return 0; } //新运算符比栈顶元素优先级高,入栈否则栈顶元素出栈运算, //直至栈顶元素运算符优先级低于要入栈的运算符或栈空;