表达式求值

来源:互联网 发布:ios与js的交互 编辑:程序博客网 时间:2024/06/05 02:18

表达式求值

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
描述
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.504.00



解题报告:数据结构题,知识点是将中缀表达式转化为后缀表达式。

理论: 中缀表达式转换为后缀表达式及后缀表达式求值

测试数据:

输入

3

(1+2)*5.156/54*4.154/47852*41463=
((1+2)*5.156/54+4.154)/47852*41463-56*78/32*0.154=

((1+2)/4+(3-5))*2=

输出:

1.03
-17.17

-2.50


code:

#include<iostream>#include<algorithm>#include<cstdio>#include<queue>#include<stack>#include<cmath>#include<string>#include<cstring>#include<ctype.h>using namespace std;typedef long long ll;const int maxn=1005;char s1[maxn],s2[maxn];int cmp(char ch){  //操作符的优先级 +-*/    if(ch=='+' || ch=='-')        return 1;    else if(ch=='*' || ch=='/')        return 2;    else        return 0;}void convert(){  //中缀表达式转化为后缀表达式    stack<char> st;    int j=0;    for(int i=0;i<strlen(s1);i++){        if(s1[i]=='('){            st.push(s1[i]);        }else if(s1[i]>='0' && s1[i]<='9'){            while((s1[i]>='0' && s1[i]<='9') || s1[i]=='.'){                s2[j++]=s1[i];                i++;            }            i--;            s2[j++]=' ';        }else if(s1[i]=='+' || s1[i]=='-' || s1[i]=='*' || s1[i]=='/'){            if(st.empty())                st.push(s1[i]);            else{                while(!st.empty() && st.top()!='(' && cmp(st.top())>=cmp(s1[i])){                    s2[j++]=st.top();                    s2[j++]=' ';                    st.pop();                }                st.push(s1[i]);            }        }else if(s1[i]==')'){            while(!st.empty()){                if(st.top()=='('){                    st.pop();                    break;                }                s2[j++]=st.top();                s2[j++]=' ';                st.pop();            }        }else{ //s1[i]== '=';            continue;        }    }    while(!st.empty()){        s2[j++]=st.top();        s2[j++]=' ';        st.pop();    }    s2[j]='\0';}void calculate(){  //计算后缀表达式的值    stack<double> st;    for(int i=0;i<strlen(s2);i++){        if(s2[i]==' ')            continue;        if(s2[i]=='+'){            double a,b;            a=st.top();            st.pop();            b=st.top();            st.pop();            st.push(a+b);        }else if(s2[i]=='-'){            double a,b;            a=st.top();            st.pop();            b=st.top();            st.pop();            st.push(b-a);  //注意这里是b-a        }else if(s2[i]=='*'){            double a,b;            a=st.top();            st.pop();            b=st.top();            st.pop();            st.push(a*b);        }else if(s2[i]=='/'){            double a,b;            a=st.top();            st.pop();            b=st.top();            st.pop();            st.push(b/a); //注意这里是b/a        }else{   //把这步放后面防止有数字0;            double sum=0;            while(s2[i]>='0' && s2[i]<='9'){ //整数部分                sum=sum*10+(s2[i]-'0');                i++;            }            if(s2[i]=='.'){ //小数部分                double m=0,k=10;                i++;                while(s2[i]>='0' && s2[i]<='9'){                    m+=((s2[i]-'0')/k);                    k*=10;                    i++;                }                sum+=m;            }            st.push(sum);        }    }    printf("%.2lf\n",st.top());}int main(){//    freopen("input.txt","r",stdin);    int t;    scanf("%d",&t);    while(t--){        getchar();        scanf("%s",s1);        convert();        calculate();    }    return 0;}



0 0
原创粉丝点击