题目1019:简单计算器 九度OJ

来源:互联网 发布:gevent 数据库 编辑:程序博客网 时间:2024/04/30 02:42
题目1019:简单计算器

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:10114

解决:3697

题目描述:
    读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
输入:
    测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
输出:
    对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
样例输入:
1 + 24 + 2 * 5 - 7 / 110
样例输出:
3.0013.36
来源:
2006年浙江大学计算机及软件工程研究生机试真题

#include <cstdio>#include <iostream>#include <stack>#include <cstring>using namespace std;stack <double> number;stack <char> s;int cmps[5][5]={0,0,0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1};int tagsure(char sym){//判断运算符编号int tag=0;switch(sym){case '=': tag=0;break;case '+': tag=1;break;case '-': tag=2;break;case '*': tag=3;break;case '/': tag=4;break;default: tag=0;break;}return tag;}int main(){string str;while(getline(cin,str)){if(str[0]=='0')break;while(!number.empty())number.pop();while(!s.empty())s.pop();str='='+str+'=';//在首尾添加优先级最低的运算符//cout<<str<<endl;int length=str.length();int bit=0;for(int i=0;i<length;i++){if(str[i]>='0'&&str[i]<='9'){if(bit==0){number.push(str[i]-48);bit=1;}else{double temp;temp=number.top()*10+str[i]-48;number.pop();number.push(temp);}}else if(str[i]==' '){bit=0;continue;}else{bit=0;if(s.empty()){s.push(str[i]);//推进去的是 首位 “= ” 号}else{int sym_top=tagsure(s.top());int sym_now=tagsure(str[i]);//栈顶运算符的优先级 大于 当前运算符str[i]while(cmps[sym_top][sym_now]){int cal=s.top();s.pop();double num1=number.top();number.pop();double num2=number.top();number.pop();double result;switch(cal){case '+': result=num2+num1;break;case '-': result=num2-num1;break;case '*': result=num2*num1;break;case '/': result=num2/num1;break;default:break;}number.push(result);sym_top=tagsure(s.top());}s.push(str[i]);}}}        printf("%.2f\n",number.top());}return 0;}

刚开始以为我这样的菜鸡要写一周。啊,结果并没有我最开始看到题那样复杂。
本题有些容易把人(把我)带坑里的地方。
1.比如读取运算式,用C的char str[210]呢?还是直接用C++的getline(cin,str)呢?用了getline()之后要不要用sstream 呢?
后来选择用C++的getline(),毕竟处理C里面的'\0'稍微有点复杂。
2.怎么判定最后一个运算符是最后一个运算符呢?
这里采用的方法可能稍显笨拙(实际上也是看了题解才采用这种方法的,保险~),在运算式字符串的首尾添加一个最低一级的运算符,这样,就不需要对首尾进行特殊处理。达到一视同仁的效果。
比如,4+2*5-7/11,在把/压入堆栈、11压入堆栈之后,对该运算式的遍历算是告一段落了,但是要用怎么样的判断语句或者是循环语句将堆栈里的-和/弹出呢? 当然,可以用此时str已油尽灯枯到了尽头的语句,使得运算符栈里的运算符挨个弹出。
这里采用的办法是将末尾最低优先级运算符与运算符栈顶的运算符进行比较,将栈顶运算符弹出。
这种方法就省去了对是否到末尾的判断行为。具有一般性。

0 0
原创粉丝点击