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;
}

原理是先轉爲逆波蘭式,然後計算

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章