算术表达式求值
算术四则运算遵循以下三条原则
- 先乘除,后加减。
- 从左到右。
- 先括号内,后括号外。
在运算的每一步,任意两个相继出现的算符op1和算法op2之间存在优先级关系,以下三种关系:op1 < op2 ,op1 > op2,op1 = op2。
算法步骤:
- 初始化操作数栈OPND, 操作符栈OPTR,表达式起始符’#'入OPTR。
- 扫描表达式,读一个字符,直至扫描完毕到’#‘结束字符或者OPTR栈顶元素不为’#'时,循环执行以下操作:
- 若ch不是运算符,压入OPND,读下一个字符ch。
- 若ch是运算符,根据ch与OPTR栈顶元素的运算符优先级结果:
- 小于,ch压入OPTR栈,读一个字符ch。
- 大于,弹出OPTR栈顶运算符,从OPND弹出两个数,进行运算结果压入OPND。
- 等于,OPTR的栈顶元素是’(‘且ch是’)’,弹出括号表示括号匹配成功,读入下一个字符ch。
- OPND栈顶元素为表达式求值的结果。
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;
// 判断ch是否为运算符
bool isOperator(char ch) {
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '#') {
return true;
} else {
return false;
}
}
/**
* 比较运算符a和b的优先级
@prama a char 运算符a
@prama b char 运算符b
@return int
1为运算符优先级 a > b
0为运算符优先级 a = b
-1为运算符优先级 a < b
*/
int compareOperator(char a, char b) {
if (a == '+') {
if (b == '+' || b == '-' || b == ')' || b == '#') {
return 1;
} else {
return -1;
}
}
if (a == '-') {
if (b == '+' || b == '-' || b == ')' || b == '#') {
return 1;
} else {
return -1;
}
}
if (a == '*') {
if (b == '(') {
return -1;
} else {
return 1;
}
}
if (a == '/') {
if (b == '(') {
return -1;
} else {
return 1;
}
}
if (a == '(') {
if (b == ')') {
return 0;
} else {
return -1;
}
}
if (a == ')') {
return 1;
}
if (a == '#') {
if (b == '#') {
return 0;
} else {
return -1;
}
}
cout << "error" << endl;
return -1;
}
// 计算a op b
int calculate(int a, int b, char op) {
if (op == '+') {
return a + b;
} else if (op == '-') {
return a - b;
} else if (op == '*') {
return a * b;
} else if (op == '/') {
return a / b;
}
cout << "error" << endl;
return -1;
}
int main() {
stack<int> OPND;// 初始化操作数栈
stack<char> OPTR; // 初始化运算符栈
OPTR.push('#'); // 表达式起始符#压入栈中
char ch;
cin >> ch;
while (ch != '#' || OPTR.top() != '#') {
if (!isOperator(ch)) {
// 操作数
OPND.push(ch - '0');
cin >> ch;
} else {
// 运算符
int res = compareOperator(OPTR.top(), ch);
if (res == -1) {
// 运算符栈 栈顶元素优先级小于ch
OPTR.push(ch);
cin >> ch;
} else if (res == 1) {
// 栈顶元素优先级高于ch
int opnd1, opnd2; // 操作数1和操作数2
char optr; // 运算符
opnd2 = OPND.top();
OPND.pop();
opnd1 = OPND.top();
OPND.pop();
optr = OPTR.top();
OPTR.pop();
// 计算
int tmp = calculate(opnd1, opnd2, optr);
OPND.push(tmp);
} else if (res == 0) {
// ()去括号
OPTR.pop();
cin >> ch;
}
}
}
cout << OPND.top() << endl;
return 0;
}