小米oj 四则运算

四则运算
序号:#16
难度:有挑战
时间限制:1000ms
内存限制:10M
描述
实现一个算法,可以进行任意非负整数的加减乘除组合四则运算。
请注意运算符的优先级。
输入
请输入一行算式,使用空格分隔数字与运算符。
数字为任意非负整数,运算符为+ - * /,不考虑括号。
输出
输出算式的运算结果。如果是小数,请向下取整(包含中间步骤结果)。
如果出现“除0异常”,输出err。
样例
3 + 5
12 + 45 / 9
1 / 2
1 / 0
12 + 34 * 56 - 78
输出样例
8
17
0
err
1838
小提示
可以使用栈来解决此类问题。
思路:
可以先将输入的表达式通过栈转换为后缀表达式。而后缀表达式可以再通过栈来计算出最终的值。
我用队列存放输入的中缀表达式和转换后的后缀表达式,转换策略为:

  1. 读取中缀表达式队列,遇到数字,直接输出。
  2. 遇到运算符,且栈为空,入栈。
  3. 遇到运算符,且栈非空,与栈顶的元素比较,若优先级大于栈顶元素,则入栈,否则输出栈顶元素到后缀表达式,pop后继续与栈顶元素比较,直到该运算符优先级大于栈顶元素或栈为空时,入栈。
  4. 若中缀表达式队列为空,直接将栈中剩余元素依次输出到后缀表达式。

后缀表达式计算时也通过栈来实现,步骤为:

  1. 读取后缀表达式队列,遇到数字,入栈。
  2. 遇到运算符,将栈最上边的两个元素弹出,并计算它们与该运算符运算的值,并将这个值入栈。
  3. 当后缀表达式队列为空时,栈中的元素为最终结果。

代码

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值