中后缀表达式的相互转换和四则运算表达式求值

这篇博客讲的超级好
//原理就是中缀表达式我们需要先转后缀表达式, 然后就可以求了.

int calculate(string s) {
    vector<string> hou;  // 后缀表达式
    stack<char>st;
    for (int i = 0 ; i < s.size() ; ++ i) { // 转后缀表达式
        if (s[i] == ' ') continue;
        if (s[i] >= '0' && s[i] <= '9') {
            int tmp = 0;
            while (i < s.size() && s[i] >= '0' && s[i] <= '9') {
                tmp = tmp * 10 + (s[i] - '0');
                ++ i;
            }
            -- i;
            hou.push_back(to_string(tmp));
        }
        else if (s[i] == '(') st.push(s[i]);
        else if (s[i] == ')') {
            while(st.top() != '(') {
                hou.push_back(string(1, st.top()));
                st.pop();
            }
            st.pop();
        }
        else {
            if (s[i] == '*' || s[i] == '/') st.push(s[i]);
            else {
                while(!st.empty() && st.top() != '(') {
                    hou.push_back(string(1, st.top()));
                    st.pop();
                }
                st.push(s[i]);
            }
        }
    }
    while(!st.empty()) {
        hou.push_back(string(1, st.top()));
        st.pop();
    }
    stack<double>num;  // 下面是求值过程
    for (int i = 0 ; i < hou.size() ; ++ i) {
        if (hou[i] == "+" || hou[i] == "-" || hou[i] == "*" || hou[i] == "/") {
            double y = num.top(); num.pop();  // 先出来的被操作运算值
            double x = num.top(); num.pop();
            num.push(cal(x, y, hou[i]));
        }
        else num.push(stod(hou[i]));
    }
    return num.top();
}

double cal(double x, double y, string op) {
    if (op == "+") return x + y;
    if (op == "-") return x - y;
    if (op == "*") return x * y;
    if (op == "/") return x / y;
}

// 下面的稍显复杂, 不过先留着mark
下面附上代码实现:
###1:中缀表达式转后缀表达式Code

const int maxn = 1e3+5;
char zhong[maxn];
char hou[maxn];
stack<char>S;

void solve()
{//这个是只有单个整数和运算符,只是直观给出后缀表达式,计算的当然不一样.
    scanf("%s",zhong);
    int len = strlen(zhong);
    int cnt = 0;
    for(int i=0;i<len;i++){   //注意一个优先级问题!!!
        if(zhong[i]>='0' && zhong[i]<='9') hou[cnt++] = zhong[i];
        else{   //也要特别注意判断运算符优先级的问题.
            if(zhong[i] == '(' ) S.push(zhong[i]);
            else if(zhong[i] == ')' ){
                while(!S.empty()){
                    char tmp = S.top();
                    S.pop();
                    if(tmp == '(' ) break;
                    hou[cnt++] = tmp;
                }
            }
            else if(zhong[i] == '*' || zhong[i] == '/'){
                while(!S.empty()){
                    char tmp = S.top();
                    if(tmp == '+' || tmp == '-' || tmp == '(') break;
                    S.pop();
                    hou[cnt++] = tmp;
                }
                S.push(zhong[i]);
            }
            else if(zhong[i] == '+' || zhong[i] == '-'){
                while(!S.empty()){
                    char tmp = S.top();
                    if(tmp == '(') break;
                    S.pop();
                    hou[cnt++] = tmp;
                }
                S.push(zhong[i]);
            }
        }
    }
    while(!S.empty()){  //有可能运算符还有.
        char tmp = S.top();
        S.pop();
        hou[cnt++] = tmp;
    }
    hou[cnt] = 0;
    printf("%s\n",hou);
}

模板题
###2 : 四则运算表达式求值(有了以上的基础,这个就比较简单)
Code

const int maxn = 1e3+5;
char zhong[maxn];
char hou[maxn];
char num[maxn];
db res[maxn];
stack<char>S;
stack<db>cal;

void solve()
{
    while(~scanf("%s",zhong)){
        Fill(hou,0); Fill(num,0); Fill(res,0);
        int len = strlen(zhong);
        int cnt = 0;
        for(int i=0;i<len;i++){
            if(zhong[i]>='0' && zhong[i]<='9'){
                int ans = 0;
                Fill(num,0);
                while((zhong[i]>='0' && zhong[i]<='9') || zhong[i] == '.'){
                    num[ans++] = zhong[i];
                    i++;
                }
                i--;
                res[cnt++] = atof(num);
            }
            else{
                if(zhong[i] == '(' ) S.push(zhong[i]);
                else if(zhong[i] == ')' ){
                    while(!S.empty()){
                        char tmp = S.top();
                        S.pop();
                        if(tmp == '(' ) break;
                        hou[cnt++] = tmp;
                    }
                }
                else if(zhong[i] == '*' || zhong[i] == '/'){
                    while(!S.empty()){
                        char tmp = S.top();
                        if(tmp == '+' || tmp == '-' || tmp == '(') break;
                        S.pop();
                        hou[cnt++] = tmp;
                    }
                    S.push(zhong[i]);
                }
                else if(zhong[i] == '+' || zhong[i] == '-'){
                    while(!S.empty()){
                        char tmp = S.top();
                        if(tmp == '(') break;
                        S.pop();
                        hou[cnt++] = tmp;
                    }
                    S.push(zhong[i]);
                }
            }
        }
        while(!S.empty()){  //有可能运算符还有.
            char tmp = S.top();
            S.pop();
            hou[cnt++] = tmp;
        }
        for(int i=0;i<cnt;i++){
            if(hou[i] == 0) cal.push(res[i]);
            else{   //注意这些的写法与之前的处理的关系.
                db t1 = cal.top();
                cal.pop();
                db t2 = cal.top();
                cal.pop();
                if(hou[i] == '+' ) cal.push(t1+t2);
                if(hou[i] == '-' ) cal.push(t2-t1);  
                //注意数被取出来的先后顺序(-和/运算有影响).
                if(hou[i] == '*' ) cal.push(t1*t2);
                if(hou[i] == '/' ) cal.push(t2/t1);
            }
        }
        printf("%.2f\n",cal.top());
        cal.pop();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值