算法题 52 简单四则运算解析器(c++)

68 阅读2分钟

问题描述

小F面临一个编程挑战:实现一个基本的计算器来计算简单的字符串表达式的值。该字符串表达式有效,并可能包含数字(0-9)、运算符+-及括号()。注意,字符串中不包含空格。除法运算应只保留整数结果。请实现一个解析器计算这些表达式的值,且不使用任何内置的eval函数。


测试样例

样例1:

输入:expression = "1+1"
输出:2

样例2:

输入:expression = "3+4*5/(3+2)"
输出:7

样例3:

输入:expression = "4+2*5-2/1"
输出:12

样例4:

输入:expression = "(1+(4+5+2)-3)+(6+8)"
输出:23

样例5:

输入:expression = "2*(5+5*2)/3+(6+8*3)"
输出:40

代码

#include <iostream>
#include <string>
#include <stack>
#include <cctype>
using namespace std;

int getPriority(char op) {
    if (op == '+' || op == '-') return 1;
    if (op == '*' || op == '/') return 2;
    return 0;
}

long long compute(long long a, long long b, char op) {
    switch (op) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return a / b;
    }
    return 0;
}

int solution(string expression) {
    stack<long long> nums;
    stack<char> ops;
    
    for (int i = 0; i < expression.size(); i++) {
        char c = expression[i];
        if (isspace(c)) continue;
        
        if (isdigit(c)) {
            long long num = 0;
            while (i < expression.size() && isdigit(expression[i])) {
                num = num * 10 + (expression[i] - '0');
                i++;
            }
            i--;
            nums.push(num);
        }
        else if (c == '(') {
            ops.push(c);
        }
        else if (c == ')') {
            while (!ops.empty() && ops.top() != '(') {
                long long b = nums.top(); nums.pop();
                long long a = nums.top(); nums.pop();
                char op = ops.top(); ops.pop();
                nums.push(compute(a, b, op));
            }
            ops.pop(); // 弹出'('
        }
        else {
            while (!ops.empty() && getPriority(ops.top()) >= getPriority(c)) {
                long long b = nums.top(); nums.pop();
                long long a = nums.top(); nums.pop();
                char op = ops.top(); ops.pop();
                nums.push(compute(a, b, op));
            }
            ops.push(c);
        }
    }
    
    while (!ops.empty()) {
        long long b = nums.top(); nums.pop();
        long long a = nums.top(); nums.pop();
        char op = ops.top(); ops.pop();
        nums.push(compute(a, b, op));
    }
    
    return nums.top();
}

int main() {
    cout << (solution("1+1") == 2) << endl;
    cout << (solution("3+4*5/(3+2)") == 7) << endl;
    cout << (solution("4+2*5-2/1") == 12) << endl;
    cout << (solution("(1+(4+5+2)-3)+(6+8)") == 23) << endl;
    cout << (solution("2*(5+5*2)/3+(6+8*3)") == 40) << endl;
    return 0;
}

思路:

首先创建两个栈:一个栈存数字,一个栈存操作符

首先遍历字符串

若当前字符为数字,则处理当前数字,将数字压入存数字的栈

若当前字符为符号,则判断当前符号与上一个符号的优先级,

若优先级低于上一个符号,则拿出数字栈顶的两个数字,和操作栈顶的符号,进行操作,得出的数字继续压入栈顶,然后当前符号也压入栈顶。

若大于上一个符号的直接压入栈顶

最后处理剩余的数字栈和字符栈

数字栈一定会剩余最后一个数字,这最后一个数字就是答案