表达式求值-中缀表达式转为后缀表达式

简单计算只包含()和+-*/的表达式

思路:先将中缀表达式转化为后缀表达式,然后计算后缀表达式的值。

规则:时刻保证栈内 上面的元素 比 下边的元素 优先级高
步骤:
1.如果当前元素 比 栈顶元素 优先级 高,那么把当前元素压入栈内能保证规则成立,所以直接压栈。
2.如果当前元素 比 栈顶元素 优先级 低,那么把栈顶元素弹出放到后缀表达式里。
3.重复第二步,直到 当前元素 比 栈顶元素 优先级 高,则当前元素压入栈内能保证规则成立,所以直接压栈。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stack>
using namespace std;

int main(){
    string s;///存原表达式
    stack <char> res;///将原表达式转化为后缀表达式所用到的符号栈
    cin>>s;
    string behind[100];///存后缀表达式的字符串数组

    int cnt = 0;///后缀表达式中字符串的个数(下标)

    ///把前缀表达式转化为后缀表达式
    for(int i = 0;i<s.length();){
        if(s[i]>='0' && s[i]<='9'){///以数字打头的一定是数字
            char temp[10];///暂时放这个数
            int t1 = 0;///这个数变成字符串时的长度(下标)
            while(s[i]>='0' && s[i]<='9'){///如果有小数可以加上s[i]=='.'
               temp[t1] = s[i];
               i++;
               t1++;
            }
            temp[t1]=0;///结束符,标志字符串已经结束
            ///数已经处理好了,直接存放到后缀表达式里
            behind[cnt] = temp;
            cnt++;
        }

        else{///如果是符号

            if(s[i] == '('){///左括号直接压栈
                res.push(s[i]);
            }
            else if(s[i] == ')'){///把左括号后的符号依次弹出,写入后缀表达式中
                while(!res.empty() && res.top() != '('){
                    string temp = " ";///声明一个string类型变量,内存空间是一个字符大小
                    temp[0] = res.top();
                    behind[cnt] = temp;
                    cnt++;
                    res.pop();
                }
                res.pop();///弹出(但是不写进后缀表达式
            }

            else if(s[i] == '+' || s[i] == '-'){///把 + - * / 弹出并写入后缀表达式
                while(!res.empty() && res.top() != '('){
                    string temp = " ";

                    temp[0] = res.top();
                    behind[cnt] = temp;
                    cnt++;
                    res.pop();
                }
                res.push(s[i]);
            }
            else{///把* / 弹出并写入后缀表达式
                while(!res.empty()&&(res.top()=='*'||res.top()=='/')){
                    string temp = " ";
                    temp[0] = res.top();
                    behind[cnt] = temp;
                    cnt++;
                    res.pop();
                }
                res.push(s[i]);
            }

            i++;
        }
    }

    while(!res.empty()){///把栈内剩余符号依次放入后缀表达式中
        string temp = " ";
        temp[0] = res.top();
        behind[cnt] = temp;
        cnt++;
        res.pop();
    }
    cout<<"后缀表达式:"<<endl;
    for(int i = 0;i<cnt;++i){
        cout<<behind[i]<<" ";
    }

    ///计算后缀表达式的值
    stack<double> q;///计算表达式值的栈
    bool error = 0;///表达式合法性判断
    for(int i = 0; i<cnt; i++){
        ///如果是符号
        if((behind[i][0]== '+' || behind[i][0]=='-' || behind[i][0]=='*' || behind[i][0]=='/')){
            if(q.size()<2) {error = 1; break;}
            double aa = q.top(); q.pop();
            double bb = q.top(); q.pop();
            if(behind[i][0]== '+') q.push(aa+bb);
            else if(behind[i][0]== '-') q.push(bb-aa);///这里注意顺序,栈顶元素是减数
            else if(behind[i][0]== '*') q.push((aa*bb));
            else if(behind[i][0]== '/') {
                if(bb==0){error = 1; cout<<"除0 ";break;}///排除除零错误
                q.push(bb/aa);///注意顺序
            }
        }
        else{
            /// c_str() 函数是string中转化为字符数组的函数
            ///atof() 是c语言中将字符数组转化为浮点型数据函数
            double x = atof(behind[i].c_str());
            q.push(x);
        }
    }

    if(q.size() != 1) error = 1;

    if(error) cout<<"ERROR";
    else cout<<endl<<"结果是:"<<q.top();

    return 0;
}


发布了229 篇原创文章 · 获赞 252 · 访问量 10万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章