我们通常把运算符号放在运算数的中间,再用括号表示优先级别,比如a+b*c 和(a+b)*c,但在计算机为了正确存储算数表达式,还需要存储括号,非常麻烦,所以人们发明了前缀和后缀表达方法。
算数表达式可以分为前缀(prefix)、后缀(postfix)、中缀(infix)。
中缀表达式是我们通常用的形式,就是把运算符号放到两个运算数中间,但需要用括号来标定优先级,这在计算机处理上比较麻烦,所以在计算机中用前缀或后缀表达式来处理。
Infix Notation | Prefix Notation | Postfix Notation |
a + b | + a b | a b + |
(a + b) * c | * + a b c | a b + c * |
a * (b + c) | * a + b c | a b c + * |
a / b + c / d | + / a b / c d | a b / c d / + |
(a + b) * (c + d) | * + a b + c d | a b + c d + * |
((a + b) * c) – d | – * + a b c d | a 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; } |