Loading

表达式求值

数学表达式求值:输入由数字、‘+’,‘—’,‘*’,‘/’,乘方’^’,小括号组成的字符串,输出运算结果;

使用栈实现。对于括号,预处理每个左括号对应的右括号位置,然后递归处理每个括号.对于判断负数要很小心,万一出现 -(-(-(-1))) 这种情况

#include<bits/stdc++.h>
using namespace std;
const int N=105;
char s[N];
int t[N],n;
unordered_map<char,int>mp;
void init() {
    scanf("%s",s+1);
    stack<int>tmp;
    n=strlen(s+1);
    for(int i=1; i<=n; ++i) {
        if(s[i]=='(')
            tmp.push(i);
        else if(s[i]==')') {
            t[tmp.top()]=i;
            tmp.pop();
        }
    }
    mp['+']=mp['-']=1;
    mp['*']=mp['/']=2;
    mp['^']=3;
}
bool isd(char c) {
    return (c>='0'&&c<='9')?true:false;
}
void js(stack<char>&a,stack<double>&b)
{
    double x=b.top();b.pop();
    double y=b.top();b.pop();
    char c=a.top();a.pop();
    if(c=='+')b.push(y+x);
    if(c=='-')b.push(y-x);
    if(c=='*')b.push(y*x);
    if(c=='/')b.push(y/x);
    if(c=='^')b.push(pow(y,x));
}
double dfs(int l,int r) {
    stack<char>s1;
    stack<double>s2;
    double neg=1;
    for(int i=l; i<=r;) {
        if(isd(s[i])) {
            double tmp=0;
            while(isd(s[i]))tmp=tmp*10+(s[i]-'0'),++i;
            if(s[i]=='.') {
                ++i;
                double sum=1;
                while(isd(s[i]))sum/=10,tmp+=sum*(s[i]-'0'),++i;
            }
            tmp*=neg,neg=1;
            s2.push(tmp);
        } else if(s[i]=='(') {
            s2.push(dfs(i+1,t[i]-1));
            i=t[i]+1;
        }
        else {
            if(s[i]=='-'&&isd(s[i+1])&&(i==1||((s[i-1]!=')'&&!isd(s[i-1]))))) {
                neg=-1,++i;
                continue;
            }
            if(!s1.empty()) {
                while(s1.size()&& mp[s1.top()]>= mp[s[i]])js(s1,s2);
                s1.push(s[i]);
                }
            else s1.push(s[i]);
            ++i;
            }
        }
    while(s1.size())js(s1,s2);
    return s2.top();
}
int main() {
    init();
    printf("%.3lf\n",dfs(1,n));
    return 0;
}
posted @ 2020-02-16 16:05  zzctommy  阅读(415)  评论(0编辑  收藏  举报