算数表达式

我们通常把运算符号放在运算数的中间,再用括号表示优先级别,比如a+b*c 和(a+b)*c,但在计算机为了正确存储算数表达式,还需要存储括号,非常麻烦,所以人们发明了前缀和后缀表达方法。

算数表达式可以分为前缀(prefix)、后缀(postfix)、中缀(infix)。
中缀表达式是我们通常用的形式,就是把运算符号放到两个运算数中间,但需要用括号来标定优先级,这在计算机处理上比较麻烦,所以在计算机中用前缀或后缀表达式来处理。

Infix NotationPrefix NotationPostfix Notation
a + b+ a ba b +
(a + b) * c* + a b ca b + c *
a * (b + c)* a + b ca b c + *
a / b + c / d+ / a b / c da b / c d / +
(a + b) * (c + d)* + a b + c da b + c d + *
((a + b) * c) – d– * + a b c da b + c * d –

洛谷:p1981

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <stack>
using namespace std;
stack <int> x;//一个存数字并在最后把它们相加的栈
int main()
{
	int a,b;
	char c;
	cin>>a;//先输入一个数,以后符号+数字输入
	int m=10000;
	a=a%m;//必须的操作
	x.push(a);//压入栈中
	while(cin>>c>>b){
		if(c=='*'){//将*之前的数字与*之后的数字积存入
		
			a=x.top();
			x.pop();
			x.push(a*b%m);
		}
		else//将b存入
			x.push(b);
	}
	a=0;
	while(x.size()){
		a+=x.top();
		x.pop();
	}
    	a%=m;//取模
	cout<<a<<endl;
	return 0;
}

acwing3302
计算式:(12+2)*(13-2*3)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**************************************************************** 
 * 代码作者: Alex Li
 * 创建时间: 2023-09-30 18:34:45
 * 最后修改: 2025-05-10 13:29:02
 * 文件描述: 输出算术式结果 例如:(12+2)/(13-2*3)
****************************************************************/
#include <bits/stdc++.h>
using namespace std;

stack<int> num; // 存储操作数的栈
stack<char> op; // 存储操作符的栈


// eval函数用于执行一次运算
void eval() {
    // 从数字栈中取出两个操作数
    int b = num.top(); num.pop(); // 获取栈顶元素并出栈(右操作数)
    int a = num.top(); num.pop(); // 获取栈顶元素并出栈(左操作数)
    
    // 从操作符栈中取出一个操作符
    char c = op.top(); op.pop();  // 获取栈顶操作符并出栈
    
    int result;
    // 根据操作符执行相应的运算
    if (c == '+') result = a + b;
    else if (c == '-') result = a - b;
    else if (c == '*') result = a * b;
    else if (c == '/') result = a / b;
    
    // 将运算结果压入数字栈
    num.push(result);
}

int main() {
    string str;
    cin >> str; // 从标准输入读取算术表达式
    
    map<char, int> pr;
    pr.emplace('+',1);
    pr.emplace('-',1);
    pr.emplace('*',2);
    pr.emplace('/',2);
    for (int i = 0; i < str.size(); i++) {
        char c = str[i];
        
        // 如果当前字符是数字
        if (isdigit(c)) { 
            int x = 0, j = i;
            // 处理可能的多位数字
            while (j < str.size() && isdigit(str[j])) {
                x = x * 10 + str[j++] - '0'; // 将字符转换为数字
            }
            i = j - 1; // 更新i以跳过处理过的数字
            num.push(x); // 将数字压入数字栈
        }
        // 如果当前字符是左括号 '('
        else if (c == '(') {
            op.push(c); // 左括号直接压入操作符栈
        }
        // 如果当前字符是右括号 ')'
        else if (c == ')') {
            // 处理括号内的表达式,直到遇到左括号
            while (op.top() != '(') eval();
            op.pop(); // 弹出左括号 '('
        }
        // 如果当前字符是操作符 '+', '-', '*', '/'
        else {
            // 处理优先级问题
            while (!op.empty() && op.top() != '(' && pr[op.top()] >= pr[c]) {
                eval(); // 如果栈顶操作符优先级大于等于当前操作符,执行运算
            }
            op.push(c); // 将当前操作符压入操作符栈
        }
    }

    // 如果表达式处理完毕,但操作符栈中仍有操作符,继续执行运算
    while (!op.empty()) eval();
    
    // 最终结果保存在数字栈的栈顶
    cout << num.top() << endl; // 输出最终结果
    return 0;
}
Scroll to Top