求解表达式的值 表达式树的运用

1061: 求解表达式的值

Time Limit: 1 Sec  Memory Limit: 10 MB
Submit: 3  Solved: 2
[ Submit][ Status][ Web Board]

Description

求解一个混合表达式的值,注意要求严格按照C语言的运算规则来求解表达式的值。

Input

 输入一个混合表达式,为了问题简单表达式中只包含+(加),-(减),*(乘),/(除)以及整数、小数和括号。

Output

 输出该表达式的值,结果保留到小数点后两位。

Sample Input

1+1
1*2+(5.0/2)
50/100+1*1.23

Sample Output

2.00
4.50
1.23
这题有两个难点,第一个难点就是处理浮点型,我的思路就是直接把浮点型处理为string;第二个难点就是“严格按照C语言的运算规则”求解表达式的值,从第三个测试样例可以看出,int型与int型运算仍为int,那么就用一个结构体存储答案和这个数的类型,在进行除法时特别判断一下它的类型就可以了。
AC代码:
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
const int maxn=1000+5;
char s[maxn];
string op[maxn];
int r[maxn],l[maxn];
int nc=0,n,fla=0;
string w[maxn];
struct node{
    int flag;
    double ans;
    node(int x,double y):flag(x),ans(y){}
};
int mart(){
    int ind=0;
    for(int i=0;i<n;++i){
        if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]==')'||s[i]=='(')
            w[ind++]=s[i];
        else {
            w[ind]="";
            while(s[i]>='0'&&s[i]<='9'||s[i]=='.'){
                w[ind]+=s[i++];
            }
            ++ind;
            --i;
        }
    }
    return ind;
}

inline double get(string p){
    fla=0;
    double ans=0;
    int h=0,len=p.size();
    for(int i=0;i<len;++i){
        if(p[i]=='.') {h=i;continue;}
        ans=ans*10+(p[i]-'0');
    }
    if(h!=0) {fla=1;return ans/pow(10,len-h-1);}
    return ans;
}
int build_tree(int x,int y){
    int c1=-1,c2=-1,p=0;
    int u;
    if(y-x==1){
        u=++nc;
        l[u]=r[u]=0;
        op[u]=w[x];
        return u;
    }
    for(int i=x;i<y;++i){
        if(w[i]=="(") p++;
        else if(w[i]==")") p--;
        else if(w[i]=="+"||w[i]=="-"){
            if(!p) c1=i;
        }
        else if(w[i]=="*"||w[i]=="/"){
            if(!p) c2=i;
        }
    }
    if(c1<0) c1=c2;
    if(c1<0) return build_tree(x+1,y-1);
    u=++nc;
    l[u]=build_tree(x,c1);
    r[u]=build_tree(c1+1,y);
    op[u]=w[c1];
    return u;
}
node solve(int u){

    if(l[u]==0&&r[u]==0) {
        double v=get(op[u]);
        return node(fla,v);
    }
    node p1=solve(l[u]);
    node p2=solve(r[u]);
    double ll=p1.ans,rr=p2.ans;

    fla=0;
    if(p1.flag||p2.flag) fla=1;
    if(op[u]=="+") return node(fla,ll+rr);
    if(op[u]=="-") return node(fla,ll-rr);
    if(op[u]=="*") return node(fla,ll*rr);
    if(op[u]=="/") {
        if(fla) return node(fla,ll/rr);
        else {
            int a=ll,b=rr;
            return node(fla,a/b);
        }
    }
}
int main(){
    while(scanf("%s",s)==1){
        nc=0;
        n=strlen(s);
        n=mart();
        int root=build_tree(0,n);
        printf("%.2f\n",solve(root).ans);
    }
    return 0;
}

如有不当之处欢迎指出!


转载于:https://www.cnblogs.com/flyawayl/p/8305532.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值