前、中、后序表达式及其转化

中序表达式就是算术表达式,也就是我们常写的 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;
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值