c++字符串表达式计算

先上代码

/*
 * @Description: Do not edit
 * @Author: taowentao
 * @Date: 2020-01-07 20:48:10
 * @LastEditors  : taowentao
 * @LastEditTime : 2020-01-07 23:12:05
 */

#include <string>
#include <stack>
#include <iostream>
#include <sstream>
#include <queue>

using namespace std;

//字符串转数字
template<typename S,typename D>
D TTrans(const S& s){
    D d;
    stringstream ss;
    ss << s;
    ss >> d;
    return d;
}

bool IsOP(const char c){
    switch (c)
    {
    case '+':
    case '-':
    case '*':
    case '/':
        return true;
    default:
        return false;
    }
}

int getPrioraty(const char c)
{
    switch (c)
    {
    case '+':
    case '-':
        return 1;
    case '*':
    case '/':
        return 2;
    default:
        return 0;
    }
}

template<typename T>
T eval(const string& exp){
    //逆波兰式栈
    queue<string> res;
    //中间栈
    stack<string> nb;
    auto it = exp.cbegin();
    auto end = exp.cend();
    while(it<end){//遍历字符串
        // auto ss = nb;
        // while(!ss.empty()){
        //     cout << ss.top() << "\t";
        //     ss.pop();
        // }
        // cout <<"debug"<< endl;
        if(isdigit(*it)||*it=='.'){
            string e;
            e += *it++;
            while (it < end&&(isdigit(*it)||*it=='.'))
            {
                e += *it;
            }
            //此时e是一个完整的数字
            // cout << e << endl;
            // res += e;
            res.emplace(e);
        }
        if (*it == '(')
        {
            nb.emplace(string()+*it++);
            continue;
        }
        if(*it==')'){
            if(nb.empty()){
                cout << "err 0" << endl;
                break;
            }
            auto e = nb.top();
            while(e!="(")
            {
                // cout << e << endl;
                // res += e;
                res.emplace(e);
                nb.pop();
                if (nb.empty()){
                    break;
                }
                e = nb.top();
                if(e!="("){
                    // cout << e << endl;
                    // res += e;
                    res.emplace(e);
                }
                nb.pop();
            }
            ++it;
        }
        if(IsOP(*it)){
            if (nb.empty())
            {
                nb.emplace(string() + *it++);
                continue;
            }
            auto e = nb.top();
            if(getPrioraty(*it)>getPrioraty(e[0])){
                nb.emplace(string() + *it++);
                continue;
            }
            while(getPrioraty(*it)<=getPrioraty(e[0])){
                // cout << e << endl;
                // res += e;
                res.emplace(e);
                nb.pop();
                if(nb.empty()){
                    break;
                }
                e = nb.top();
            }
            nb.emplace(string() + *it++);
            continue;
        }
    }
    while(!nb.empty()){
        auto e = nb.top();
        // cout << e << endl;
        // res += e;
        res.emplace(e);
        nb.pop();
    }
    string e;
    stack<T> ds;
    
    while(!res.empty()){
        e = res.front();
        res.pop();
        if(IsOP(e[0]))
        {
            auto a = ds.top();
            ds.pop();
            auto b = ds.top();
            ds.pop();
            T c;
            switch (e[0])
            {
            case '+':
                c = a + b;
                break;
            case '-':
                c = b - a;
                break;
            case '*':
                c = a * b;
                break;
            case '/':
                c = b / a;
                break;
            default:
                break;
            }
            // cout << b << e[0] << a << "=" << c << endl;
            ds.emplace(c);
        }else{
            ds.emplace(TTrans<string, T>(e));
        }
    }
    // cout << ds.top() << endl;
    return ds.top();
}

int main(int argc, char const *argv[])
{
    string exp = "2*(9+6/5-5)+4";
    cin >> exp;
    cout << eval<double>(exp) << endl;
    return 0;
}

原理是先转为逆波兰式,然后计算

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值