3.2.5 表示式求值

卑以自牧lq發表於2024-06-11

表示式求值

資料結構 嚴蔚敏版

3.2.5 表示式求值,c++ 程式碼實現。

注意:
輸入表示式不能有空格

#include <stack>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <iostream>
#include <iomanip>
using namespace std;

vector<vector<char>> precedence {
    //         +     -    *    /    (    )    #
    /*  +  */ {'>', '>', '<', '<', '<', '>', '>'},
    /*  -  */ {'>', '>', '<', '<', '<', '>', '>'},
    /*  *  */ {'>', '>', '>', '>', '<', '>', '>'},
    /*  /  */ {'>', '>', '>', '>', '<', '>', '>'},
    /*  (  */ {'<', '<', '<', '<', '<', '=', '$'},
    /*  )  */ {'>', '>', '>', '>', '$', '>', '>'},
    /*  #  */ {'<', '<', '<', '<', '<', '$', '='}
};

// 定義運算子對應的索引
unordered_map<char, int> opIndex = {
    {'+', 0},
    {'-', 1},
    {'*', 2},
    {'/', 3},
    {'(', 4},
    {')', 5},
    {'#', 6}
};

char comparePrecedence(char op1, char op2) {
    return precedence[opIndex[op1]][opIndex[op2]];
}

void printStack(const stack<int>& st1, const stack<char>& st2) {
    stack<int> tmp(st1);
    string res1;
    while (!tmp.empty()) {
        res1 = to_string(tmp.top()) + " " + res1;
        tmp.pop();
    }

    stack<char> tmp1(st2);
    string res2;
    while (!tmp1.empty()) {
        string ch;
        ch += tmp1.top();
        res2 = ch + " " + res2;
        tmp1.pop();
    }
    cout << std::left << std::setw(20) << "opnd: " + res1 << std::left << std::setw(40)  << "optr : " + res2 << endl;
}

int calculate(int a, int b, char op) {
    switch (op) {
    case '+':
        return a + b;
    case '-':
        return a - b;
    case '*':
        return a * b;
    case '/':
        return a / b;
    default:
        break;
    }
    printf("Wrong operator: %c!\n", op);
    return INT_MAX;
}

int evaluateExpression(const string& exp) {
    stack<char> optr;
    optr.push('#');
    stack<int> opnd;
    string str = exp + '#';
    unsigned i = 0;
    char ch = str[i];
    while (i < str.size() && (ch != '#' || !optr.empty())) {
        if (ch >= '0' && ch <= '9') {
            int num = 0;
            while (i < str.size() && ch >= '0' && ch <= '9') {
                num = num * 10 + (ch - '0');
                ch = str[++i];
            }
            opnd.push(num);
            printStack(opnd, optr);
        } else {
            switch (comparePrecedence(optr.top(), ch)) {
            case '<':
                optr.push(ch);
                ch = str[++i];
                break;
            case '=':
                optr.pop();
                ch = str[++i];
                break;
            case '>':
            {
                char op = optr.top();
                optr.pop();
                int num1 = opnd.top();
                opnd.pop();
                int num2 = opnd.top();
                opnd.pop();
                opnd.push(calculate(num2, num1, op));
                break;
            }
            default:
                printf("wrong expression!\n");
                return INT_MAX;
            }
            printStack(opnd, optr);
        }
    }

    return opnd.top();
}

int main()
{
    string exp = "3*(7-2)";
    int res = evaluateExpression(exp);
    cout << "res: " << res << endl;

    return 0;
}

執行結果:

opnd: 3             optr : #
opnd: 3             optr : # *
opnd: 3             optr : # * (
opnd: 3 7           optr : # * (
opnd: 3 7           optr : # * ( -
opnd: 3 7 2         optr : # * ( -
opnd: 3 5           optr : # * (
opnd: 3 5           optr : # *
opnd: 15            optr : #
opnd: 15            optr :
res: 15

相關文章