nyoj 35 267 表达式求值

来源:互联网 发布:车铣复合编程 编辑:程序博客网 时间:2024/06/06 16:26
ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组运算式的运算结果,输出结果保留两位小数。
样例输入
21.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;} 
原创粉丝点击