nyoj 35 267 表达式求值

ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
2
1.000+2/4=
((1+2)*5+1)/4=
样例输出            1.50            4.00 这题以前做过一次,这次直接上代码吧,可能现在写要费些时间了,干脆把代码写注释吧
//nyoj 35

#include<iostream>
#include<cstring>
#include<sstream>
#include<string>
#include<cstring>
#include<iomanip>
#include<stack>
using namespace std;
 char mid[1008],post[1008];           //前缀,后缀表达式
char compare(char c,char d)        //比较优先级 
{
     switch(c)
     {
     case '+':
     case '-':if(d=='+'||d=='-'||d==')'||d=='=') return '>';else return '<';break;
     case '*':
     case '/':if(d=='+'||d=='-'||d=='*'||d=='/'||d==')'||d=='=') return '>';else return '<';break;
     case '(':if(d==')') return '='; if(d=='=') return '>';else return '<';break;
     case ')':if(d=='(') return '='; return '>';break;
     case '=':if(d=='=') return '='; else return '<';break;
     }
}
//字符串转换为double 
double To(char a[])             //sstream头文件中的函数
{
       stringstream oss;
       oss<<a;
       double result;
       oss>>result;
       return result;
}
bool ischar(char c)            //判断是否为操作符
{
     if(c=='+'||c=='-'||c=='*'||c=='/'||c=='=') return true;
     return false;
}
void change(char mid[],char post[])            //前缀表达式变后缀表达式
{
     stack<char> s1;                            //存入栈中
     char a[1000];
     s1.push('=');                       //压入操作符 =
     int i=0,m=-1,l=strlen(mid);            
     while(i<l)
     {
       char ch;
       if((mid[i]>='0'&&mid[i]<='9')||(mid[i]=='.'))         //数字及小数点一起压入后缀表达式中
       {
        post[++m]=mid[i];
        i++;
       }
       else
      {
      post[++m]=' ';     //加入一个空格,方便转换数据
      if(compare(s1.top(),mid[i])=='<')  { s1.push(mid[i]);i++;}         //栈外符号优先级大于栈内,压入
      else if(compare(s1.top(),mid[i])=='>') { ch=s1.top();s1.pop();post[++m]=ch;}           //退栈,并放入后缀表达式中
      else if(compare(s1.top(),mid[i])=='=') { s1.pop();++i;}         //退栈
      }
   }                          
} 
double Operator(double a,char b,double c)         //运算
{
       if(b=='+') return a+c;
       if(b=='-') return a-c;
       if(b=='*') return a*c;
       if(b=='/') return a/c;
}   
double run(char post[])            //后缀表达式计算
{
       int l=strlen(post);
       int i=0,flag=0;
       stack<double> str;         //有栈来存储结果
       char q[20];            //用来转换 数据
       memset(q,0,20);
       int j=-1;
       double result,x,y;
       while(i<l)
       {
         if(post[i]>='0'&&post[i]<='9'||post[i]=='.')
         {
          q[++j]=post[i];
          flag=1;               //若为含有小数的数据,直到为空格或者操作符才进行转换
          ++i;
          continue;
         }
         else
         {
          if(flag==1)  {
          result=To(q);flag=0;j=-1;str.push(result);     //转换数据 压入栈内
          memset(q,0,20);
          }
          if(post[i]==' ') i++;          //空格为无效数据,只是方便转换
          if(ischar(post[i]))           //操作符则进行运算,把结果压入栈内
          {
           x=str.top();str.pop(); y=str.top(); str.pop();      
           str.push(Operator(y,post[i],x));++i;
          }
         }
       }
         return str.top();       //返回结果
}         
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
     cin>>mid;
     change(mid,post);
     cout<<setiosflags(ios::fixed)<<setprecision(2)<<run(post)<<endl;
     memset(post,0,1008);
    }
   //  system("pause");
    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值