中序表达式就是算术表达式,也就是我们常写的 3 + 4 × ( 5 + 6) - 8 / 2 这种式子,它的特点就是不包含括号,而且操作符位于两个操作数中间。
前序表达式也被称为前缀表达式、波兰表示法,它与中序表达式的区别就是没有括号,而且操作符位于两个操作数前面,比如上面的式子转化为前序表达式就是 - + 3 × 4 + 5 6 / 8 2
同理,后续表达式被称为逆波兰表示法,它也没有括号,而且操作符位于两个操作数后面。上面的式子转为后序表达式就是3 4 5 6 + × + 8 2 / -
先来讲讲手工算法,以后序表达式为例:先找出优先级最高的符号,然后将该操作符对应的两个操作数写到相应位置,再在后面写下操作符(注意哦,不能写括号),将写下的这部分作为一个整体,重复该操作直到没有操作符。
如果还不会手工算的可以看下别人的视频:https://www.bilibili.com/video/BV1mE411M7kT?p=1&vd_source=b2ef89badf54086338e9e9751ccdb32e
以下是将中序表达式改为后续表达式的代码,若想改为前序表达式只需将三个被注释的部分改变下就好。
// 前、中、后缀表达式.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <iostream>
#include <stack>
#include<string>
using namespace std;
/* 返回1表示c1优先级大于c2
返回0表示优先级小于c2
*/
bool compare1(char c1, char c2) {
switch (c1) {
case '+': case '-':
if ((c2 == '*') || (c2 == '/')) {
return 0;
}
else { return 1; }
break;
case '*': case '/':
if ((c2 == '+') || (c2 == '-') || (c2 == '(')) {
return 1;
}
else { return 0; }
break;
default:
cout << "请输入正确的符号" << endl;
}
return 0;
}
//中缀转后缀
int main()
{
stack<string> q; //该栈存放数字或者运算后的字符串
stack<char> tem; //该栈存放运算符
string s = "3+4*(5+6)-8/2"; //输入中序表达式
for (int i = 0; i < s.length(); ) {
string t = "";
while ((s[i] >= '0') && (i < s.length())) { t += s[i]; i++; } //获取完整的数,因为运算符的ASCII值小于‘0’;
if (t.length() > 0) { q.push(t); } //如果是数字,那就将数字输入
else { //是运算符,判断优先级
i++;
char c1 = s[i];
if (tem.empty()) { //tem队列为空,直接入队
tem.push(c1);
}
else { //队列不为空,判断优先级
if ((c1 == '(') || (c1 == ')')) { //如果是括号
if (c1 == '(') { tem.push(c1); }
else {
char c = tem.top();
while (c != '(') { //写入后缀表达式
tem.pop();
string num1 = q.top();
q.pop();
num1 = q.top() + num1 + c;
//num1 = c+q.top()+num1; //改为前序
q.pop();
q.push(num1);
c = tem.top();
}
tem.pop();
}
}
else { //不是括号
char c2 = tem.top();
bool k = compare1(c1, c2);
if (k) { //c1优先级大于c2
tem.push(c1);
}
else { //c1优先级小于c2,写入c2的后缀表达式
tem.pop();
tem.push(c1);
string t2 = q.top();
q.pop();
string t3 = q.top();
q.pop();
q.push(t3 + t2 + c2);
//q.push(c2+t3+t2); //改为前序
}
}
}
}
}
while (!tem.empty()) { //写入剩下的后缀表达式
char c = tem.top();
tem.pop();
string num1 = q.top();
q.pop();
num1 = q.top() + num1 + c;
//num1 = c+q.top()+num1; //改为前序
q.pop();
q.push(num1);
}
string result = q.top();
q.pop();
cout << result << endl; //结果为3456+*82/-+, 结果是一样的,只是加减顺序换了一下
return 0;
}