中缀转后缀并求值(简单计算器的核心)

中缀转后缀并求值

做一个简单的计算器,关键的技术就是表达式求值

将中缀表达式转化为后缀表达式

string s 为原始表达式, stack S作为操作符栈, vector V存储后缀表达式结果

如果是操作字符,分一下几种情况

(优先级说明:乘除的优先级,高于加减;’)’的优先级最低,‘(’的优先级最高)

  1. 如果字符栈为空,直接将操作符入栈 S

  2. 如果栈顶元素的优先级低于操作字符,直接入栈;

  3. 如果栈顶元素的优先级高于操作字符,字符栈S执行Pop操作,Pop出来的字符放入V直到,栈顶元素的优先级低于操作字符,才将操作符入栈; (‘(‘不考虑出栈,除非遇到4的情况)

  4. 最后,把字符栈S中的元素依次Pop出来,放入V中,这时候V所存储的就是转化后的后缀表达式

通过后缀表达式,求出表达式的值

比如表达式(-1.23-1.22) x 3转化为后缀表达式为“-1.23#1.22#-#3#x”(#分隔每个元素)

定义一个double栈 S

  1. 遍历后缀表达式V

    • 如果元素为数字,直接入栈S

    • 如果元素为操作符, 栈S, pop出两个double操作数a, b利用操作符对a,b 进行算术运算,注意如果操作符是减号应该是 b-a, 把最终结果入栈S

  2. 最后栈只会有一个double数,这个数就是最后结果,pop出来。

c++代码

#include<iostream>
#include<stack>
#include<vector>
#include<cstdlib>
#include<limits.h>
using namespace std;

bool isNum(char ch) {
    if(ch >= '0' && ch <= '9') return true;
    else return false;
}

bool isOperate(char ch) {
    if(ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')')
    return true;
    else return false;
}

int level(char ch) {
    switch(ch) {
        case '(' :
            return 5;
        case '*' :
            return 4;
        case '/' :
            return 4;
        case '+' :
            return 3;
        case '-' :
            return 3;
        case ')':
            return 2;
    }
}
/*字符串转数字*/
double scd(string s) {
    if(s.length() == 0) return INT_MAX;

    bool flag = false;
    for(int i = 0; i < s.length(); i++) {
        if(i == 0 && s[i] == '-') continue;
        else if(s[i] == '.' && !flag) {
            if(i > 0 && isNum(s[i-1])) {
                flag = true;
                continue;
            }
            else return INT_MAX;
        }
        else if(isNum(s[i])) continue;
        else return INT_MAX;
    }

    double result = atof(s.c_str());
    return result;
}

 /*由中缀表达式得到后缀表达式, 向量V存储结果*/ 
vector<string> midToPost(string s) {
    stack<char> S; /*符号栈*/
    vector<string> V; /*后缀表达式*/
    int i = 0;
    while(i < s.length()) {
        if(isNum(s[i])) {
            string str = "";
            while(isNum(s[i]) || s[i] == '.') {
                str += s[i];
                i++;
            }
            V.push_back(str);
        }

        else if(isOperate(s[i])){
            /*负数情况*/ 
            if(s[i] == '-' && i > 0 && !isNum(s[i-1])) {
                string str = "-"; i++;
                while(isNum(s[i]) || s[i] == '.') {
                    str += s[i]; i++;
                }
                V.push_back(str);       
            }else{
                if(S.empty()){
                    S.push(s[i]); i++; 
                }else {
                    int initial = level(s[i]);
                    if(initial == 2) {
                        while(level(S.top()) != 5 && !s.empty()) {
                            string str = "";
                            str += S.top();
                            V.push_back(str);
                            S.pop();
                        }
                        if(S.top() == '(') S.pop(); i++;
                    } else { 
                        while(initial <= level(S.top()) && level(S.top()) != 5 && !S.empty()) {
                            string str = "";
                            str += S.top();
                            V.push_back(str);
                            S.pop();
                        }
                        S.push(s[i]); i++;
                    }
                }
            }
        }
        else{
            cout << "表达式出错" << endl; 
            V.clear(); 
            return V;
        }
    }
    while(!S.empty()) {
        string str = ""; str += S.top();
        S.pop();
        V.push_back(str);
    }
    //for(int i = 0; i < V.size(); i++) cout << V[i] << "[]";
    return V;
}

/*后缀表达式得到最终结果*/
double getValue(vector<string> V) {
    stack<double> S;
    for(int i = 0; i < V.size(); i++) {
    /*操作运算符*/ 
        if(V[i].length() == 1 && isOperate(V[i][0])) {
            double a = 0, b = 0;
            if(!S.empty()) {
                a = S.top(); S.pop();
            }else return INT_MAX;

            if(!S.empty()) {
                b = S.top(); S.pop();
            }else return INT_MAX;

            switch(V[i][0]) {
                case '+':
                    S.push(b+a);
                    break;
                case '-':
                    S.push(b-a);
                    break;
                case '*':
                    S.push(b*a);
                    break;
                case '/':
                    S.push(b/a);
                    break;
                default:
                    return INT_MAX;
            }
        }else {
            if(scd(V[i]) == INT_MAX) return INT_MAX;
            else S.push(scd(V[i]));
        }
    }
    if(S.empty()) return INT_MAX;

    double value = S.top();
    S.pop(); 
    return value;   
} 

int main() {
    string s; /*输入的字符串s*/
    vector<string> V; /*后缀表达式*/

    cin >> s; 
    V = midToPost(s);
    if(getValue(V) == INT_MAX) {
        cout << "表达式出错" << endl; 
    }
    else cout << getValue(V) << endl;
} 

猜你喜欢

转载自blog.csdn.net/zycxnanwang/article/details/78030464
今日推荐