四则运算
序号:#16
难度:有挑战
时间限制:1000ms
内存限制:10M
描述
实现一个算法,可以进行任意非负整数的加减乘除组合四则运算。
请注意运算符的优先级。
输入
请输入一行算式,使用空格分隔数字与运算符。
数字为任意非负整数,运算符为+ - * /,不考虑括号。
输出
输出算式的运算结果。如果是小数,请向下取整(包含中间步骤结果)。
如果出现“除0异常”,输出err。
样例
3 + 5
12 + 45 / 9
1 / 2
1 / 0
12 + 34 * 56 - 78
输出样例
8
17
0
err
1838
小提示
可以使用栈来解决此类问题。
思路:
可以先将输入的表达式通过栈转换为后缀表达式。而后缀表达式可以再通过栈来计算出最终的值。
我用队列存放输入的中缀表达式和转换后的后缀表达式,转换策略为:
- 读取中缀表达式队列,遇到数字,直接输出。
- 遇到运算符,且栈为空,入栈。
- 遇到运算符,且栈非空,与栈顶的元素比较,若优先级大于栈顶元素,则入栈,否则输出栈顶元素到后缀表达式,pop后继续与栈顶元素比较,直到该运算符优先级大于栈顶元素或栈为空时,入栈。
- 若中缀表达式队列为空,直接将栈中剩余元素依次输出到后缀表达式。
后缀表达式计算时也通过栈来实现,步骤为:
- 读取后缀表达式队列,遇到数字,入栈。
- 遇到运算符,将栈最上边的两个元素弹出,并计算它们与该运算符运算的值,并将这个值入栈。
- 当后缀表达式队列为空时,栈中的元素为最终结果。
代码
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<sstream>
using namespace std;
int main(){
string x;
queue<string> ex; //ex用来存放中缀表达式
while(cin>>x){
ex.push(x);
}
queue<string> expre; //expre用来存放后缀表达式
stack<string> sta;
while(!ex.empty()){ //中缀表达式转换为后缀表达式
if(ex.front()!="+"&&ex.front()!="-"&&ex.front()!="*"&&ex.front()!="/"){
expre.push(ex.front());
ex.pop();
}
else if(sta.empty()){
sta.push(ex.front());
ex.pop();
}
else if((sta.top()=="+"||sta.top()=="-")&&(ex.front()=="*"||ex.front()=="/")){
sta.push(ex.front());
ex.pop();
}
else if(ex.front()=="*"||ex.front()=="/"){
do{
expre.push(sta.top());
sta.pop();
}
while(!sta.empty()&&sta.top()!="+"&&sta.top()!="-");
sta.push(ex.front());
ex.pop();
}
else if(ex.front()=="+"||ex.front()=="-"){
do{
expre.push(sta.top());
sta.pop();
}
while(!sta.empty());
sta.push(ex.front());
ex.pop();
}
}
while(!sta.empty()){
expre.push(sta.top());
sta.pop();
}
while(!expre.empty()){ //后缀表达式求值
if(expre.front()!="+"&&expre.front()!="-"&&expre.front()!="*"&&expre.front()!="/"){
sta.push(expre.front());
expre.pop();
}
else{
int a,b,c;
string s;
stringstream ss;
ss<<sta.top();
ss>>a;
sta.pop();
ss.clear();
ss<<sta.top();
ss>>b;
sta.pop();
ss.clear();
if(expre.front()=="+")
a=a+b;
if(expre.front()=="-")
a=b-a;
if(expre.front()=="*")
a=a*b;
if(expre.front()=="/"){
if(a==0){
cout<<"err";
return 0;
}
a=b/a;
}
ss<<a;
ss>>s;
sta.push(s);
expre.pop();
}
}
cout<<sta.top();
return 0;
}