表达式介绍
- 中缀表达式:有运算优先级的算术表达式。eg:12+4(3+5)=34
- 后缀表达式:运算优先级排序完成的运算符在操作数之后的表达式,后缀表达式的计算为遇到运算符取运算符前最近的两个操作数进行相应的运算符计算。eg:13#4#2/+=13+4/2=15
中缀表达式的运算逻辑
- 中缀表达式转后缀表达式
转换过程需要两个栈,输出栈,运算符栈。
操作:
- 读入操作数,直接压入输出栈。
- 读入运算符,压入运算运算符号栈:
✳ 若后进的运算符优先级高于先进的,直接压入运算符栈,默认’(‘优先级最高。
✳ 若后进的运算符优先级不高于(低于或等于)先进的,则将运算符号栈内不低于(高于或等于)的运算符依次弹出并压入输出栈,之后该后进运算符压入运算符栈。
✳ 括号的处理,默认’(‘优先级最高,‘)‘优先级最低,读入’(‘直接压入运算符栈,读入‘)’,弹出运算符栈所有符号并压入输出栈,直到读到’)‘停止,’)‘不从运算符栈弹出但是不压入输出栈。
✳ 两个操作数之间用’#'分割。 - 结束读取后,输出栈为后缀表达式。
- 后缀表达式求值
后缀表达式求值需要一个数栈用于存储数字。
✳ 读入操作数直接压入数栈。
✳ 读入运算符一次弹出数栈中的两个数,进行相应的运算符计算,计算结果再次压入数栈。
✳ 结束后数栈中有且仅有一个数,为结果。
C++代码
#include <bits/stdc++.h>
using namespace std;
typedef double ElemType;
int getPriority (char op) {
if (op == ')') return 0;
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
if (op == '^') return 3;
if (op == '(') return 4;
return -1;
}
string getPostfixExpression(string str) {
string result;
stack<char> opstack;
for (int i = 0; i < str.size(); i++) {
if (str[i] >= '0' && str[i] <= '9') {
if (i && !(str[i - 1] >= '0' && str[i - 1] <= '9')
&& result.size() && result[result.size() - 1] >= '0' && result[result.size() - 1] <= '9') result += '#';
result += str[i];
}
else {
if (opstack.empty() || getPriority(str[i]) > getPriority(opstack.top())) {
opstack.push(str[i]);
}
else {
while (!opstack.empty() && opstack.top() != '(' && getPriority(str[i]) <= getPriority(opstack.top())) {
result += opstack.top();
opstack.pop();
}
if (str[i] == ')') opstack.pop();
else opstack.push(str[i]);
}
}
}
while (!opstack.empty() && opstack.top() != '(') {
result += opstack.top();
opstack.pop();
}
return result;
}
ElemType postExpresionAl(string str) {
stack<ElemType> numstack;
int i = 0;
while (i < str.size()) {
if (str[i] == '#') {
i++;
continue;
}
else if (str[i] >= '0' && str[i] <= '9') {
ElemType nums = 0;
while (str[i] >= '0' && str[i] <= '9') {
nums = nums * 10 + str[i] - '0';
i++;
}
numstack.push(nums);
}
else {
ElemType a = numstack.top();
numstack.pop();
ElemType b = numstack.top();
numstack.pop();
switch (str[i]) {
case '+':
numstack.push(b + a);
break;
case '-':
numstack.push(b - a);
break;
case '*':
numstack.push(b * a);
break;
case '/':
numstack.push(b / a);
break;
case '^':
numstack.push(pow(b, a));
break;
default:
break;
}
i++;
}
}
return numstack.top();
}
int main () {
string str;
while (cin >> str) {
str = getPostfixExpression(str);
cout << str << endl;
cout << postExpresionAl(str) << endl;
}
return 0;
}