中缀表达式转变成后缀表达式:
- 定义运算符优先级
- 数字直接输出
- 遇到操作符:
- s1. 如果栈为空,直接入栈;
- s2. 如果该操作符优先级大于栈顶操作符,直接入栈;
- s3. 如果该操作符优先级低于栈顶,将栈内高(同)优先级操作符出栈,直到栈空或者遇见左括号
运算后缀表达式:
- 遇到操作数入栈
- 遇到操作符弹出两个操作数进行计算
代码实现
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <bits/stdc++.h>
using namespace std;
// 定义操作符的优先级
int priority(char opera) {
int priorit = -1;
switch (opera) {
case '+':
case '-':
priorit = 1;
break;
case '*':
case '/':
priorit = 2;
break;
case '(':
priorit = 0;
break;
default:
break;
}
return priorit;
}
// 判断当前元素是否是操作符
bool isOper(char c) {
return c == '+' || c == '-' || c == '*' || c == '/';
}
// 计算
bool calculateVal(char oper, int &num1, int num2) {
switch (oper) {
case '+':
num1 += num2;
break;
case '-':
num1 -= num2;
break;
case '*':
num1 *= num2;
break;
case '/':
if (0 == num2) {
printf("除数不为0");
return false;
}
num1 /= num2;
break;
default:
return false;
}
return true;
}
/**
* 中缀表达式转后缀
* @param infix
* @param suffix
* @return
*/
bool infix2Suffix(string infix, string &suffix) {
int len = infix.length();
if (len == 0) return false;
int j = 0;
stack<char> oStack;
for (int i = 0; i < len; i++) {
if ('(' == infix[i]) {
oStack.push('('); // 左括号直接入栈
} else if (')' == infix[i]) {
// 右括号
while (oStack.top() != '(') {
// 将左括号前的运算符全部出栈
suffix += oStack.top();
oStack.pop();
}
oStack.pop(); // 左括号出栈
} else if (isdigit(infix[i])) {
// 数字
while (isdigit(infix[i])) {
// 一直读到非数字的位置
suffix += infix[i++];
}
i--;
suffix += ' '; // 插入空格区分多个连续的数字
} else if (isOper(infix[i])) {
// 操作符
while (!oStack.empty() && priority(infix[i]) <= priority(oStack.top())) {
// 弹出所有优先级高于等于该操作符的操作符
suffix += oStack.top();
oStack.pop();
}
oStack.push(infix[i]);
}
}
while (!oStack.empty()) { // 弹出剩余的操作符写入后缀表达式
suffix += oStack.top();
oStack.pop();
}
}
bool calculateSuffix(string suffix) {
int len = suffix.length();
if (len == 0) return false;
stack<int> nStack; // 操作数栈
int num2 = 0; // 用来拼接当前连续数字
int num1 = 0;
for (int i = 0; i < len; ++i) {
if (' ' == suffix[i]) {
// 空格直接略过
continue;
} else if (isdigit(suffix[i])) {
while (isdigit(suffix[i])) {
// 将字符串中连续的单个数字拼成完整的整数
num2 = num2 * 10 + (suffix[i++] - '0'); // char 转 int
}
nStack.push(num2); // 将整数压入栈中
i--; // i 复位
num2 = 0; // tempNum 复位,用以下次的拼接
} else if (isOper(suffix[i])) {
// 遇到操作符,弹出两个操作数
num2 = nStack.top();
nStack.pop();
num1 = nStack.top();
nStack.pop();
// 计算两个数
calculateVal(suffix[i], num1, num2);
// 将结果重新压入栈
nStack.push(num1);
num2 = 0; // 复位
}
}
// 计算完成后打印结果
cout << "后缀表达式的计算结果为:" << suffix << " = " << nStack.top() << endl;
}
int main() {
string infixString; // 前缀表达式
string suffixString; // 后缀表达式
while (cin >> infixString) { // 循环输入
infix2Suffix(infixString, suffixString);
cout << "中缀表达式转后缀表达式为: " << infixString << " = " << suffixString << endl;
calculateSuffix(suffixString);
suffixString.clear();
// printf("中缀表达式: %s 转后缀为: %s",infixString,suffixString);
}
运行结果