前中后缀表达式学习笔记

前言

表达式是数学和计算机编程中常见的概念,用于表示运算和计算过程。前缀、中缀和后缀表达式都是不同的方式来表示数学表达式,它们在计算机科学和计算器设计中都有一定的应用。

中缀表达式(Infix Expression):
这是最常见的数学表达式表示方法,也是人们通常在书写数学公式时使用的方式。中缀表达式中,运算符位于操作数之间。例如:3 + 5 * 2。然而,中缀表达式在计算机内部求值时需要考虑运算符的优先级和括号的影响,这使得计算过程相对复杂。

前缀表达式(Prefix Expression):
前缀表达式也称为波兰式(Polish Notation),它将运算符放在操作数之前。例如:+ 3 * 5 2。前缀表达式的一个优点是,不需要考虑运算符的优先级和括号,计算过程相对简单。为了计算前缀表达式,可以使用堆栈数据结构来辅助计算。

后缀表达式(Postfix Expression):
后缀表达式也称为逆波兰式(Reverse Polish Notation,RPN),它将运算符放在操作数之后。例如:3 5 2 * +。与前缀表达式类似,后缀表达式也不需要考虑运算符的优先级和括号,计算过程较为简单。计算后缀表达式同样可以使用堆栈来实现。

通过将中缀表达式转换为前缀或后缀表达式,可以简化表达式的计算过程。这在编写计算器、编译器和计算机代数系统等领域中都有应用

中缀表达式转换为后缀表达式

在初赛中前中后缀表达式是个考点

当将中缀表达式转换为后缀表达式时,可以使用堆栈来辅助处理运算符和操作数。以下是将中缀表达式转换为后缀表达式的详细过程:

创建一个空堆栈,用于存放运算符。

初始化一个空列表,用于存放最终的后缀表达式。

从左到右遍历中缀表达式的每个字符:

1.遇到操作数(数字)时,将其添加到后缀表达式列表中。

遇到运算符时,需要考虑运算符的优先级以及堆栈中已有的运算符。

a. 如果堆栈为空,或者堆栈顶部的运算符为左括号 "(",直接将当前运算符入栈。

b. 如果当前运算符为 "+" 或 "-",而堆栈顶部的运算符不是左括号 "(",则将堆栈中的所有运算符弹出并加入后缀表达式列表中,直到堆栈为空或者遇到左括号为止,然后将当前运算符入栈。

c. 如果当前运算符为 "" 或 "/",而堆栈顶部的运算符为 "" 或 "/",也将堆栈中的所有运算符弹出并加入后缀表达式列表中,然后将当前运算符入栈。

d. 对于其他运算符,直接将当前运算符入栈。

2.遇到左括号 "(" 时,直接将其入栈。

3.遇到右括号 ")" 时,将堆栈中的运算符弹出并加入后缀表达式列表中,直到遇到匹配的左括号为止,然后将左括号弹出,但不加入后缀表达式列表。

4.遍历完整个中缀表达式后,将堆栈中剩余的运算符依次弹出并加入后缀表达式列表。

5.最终得到的后缀表达式列表就是转换后的后缀表达式。

例如,将中缀表达式 3 + 5 * 2 转换为后缀表达式:

第一次遍历到3,发现是数字,就把它放进列表里

运算符栈:

后缀表达式列表:3

第二次遍历到+,发现是符号,而堆栈顶部的运算符不是左括号,就把它push进栈里

运算符栈:+

后缀表达式列表:3

第三次遍历到5,发现是数字,就把它放进列表里

运算符栈:+

后缀表达式列表:3 5

第四次遍历到,发现堆栈顶部的运算符不为 "" 或 "/",就把它push进栈里

运算符栈:+ *

后缀表达式列表:3 5

第五次遍历到2,发现是数字,就把它放进列表里

运算符栈:+ *

后缀表达式列表:3 5 2

所以后缀表达式为3 5 2 * +

例如,将中缀表达式 1+14(5+1-4) 转换为后缀表达式:

第一次遍历到1,发现是数字,就把它放进列表里

运算符栈:

后缀表达式列表:1

第一次遍历到+,发现是符号,而堆栈顶部的运算符不是左括号,就把它push进栈里

运算符栈:+

后缀表达式列表:1

第二次遍历到1,发现是数字,就把它放进列表里

运算符栈:+

后缀表达式列表:1 1

第三次遍历到,发现堆栈顶部的运算符不为 "" 或 "/",就把它push进栈里

运算符栈:+ *

后缀表达式列表:1 1

第四次遍历到4,发现是数字,就把它放进列表里

运算符栈:+ *

第五次遍历到,发现堆栈顶部的运算符为 "" ,则一直弹到不为 "*" 或 "/"为止

运算符栈:+ *

后缀表达式列表:1 1 4 *

第六次遍历到"(",把它push进栈里

运算符栈:+ * (

后缀表达式列表:1 1 4 *

第七次遍历到"5",就把它放进列表里

运算符栈:+ * (

后缀表达式列表:1 1 4 * 5

第八次遍历到"+",发现堆栈顶部的运算符是左括号 "(",把它push进栈里

运算符栈:+ * ( +

后缀表达式列表:1 1 4 * 5

第九次遍历到"1",就把它放进列表里

运算符栈:+ * ( +

后缀表达式列表:1 1 4 * 5 1

第十次遍历到"-",发现堆栈顶部的运算符不是左括号 "(",将堆栈中的所有运算符弹出并加入后缀表达式列表中,直到堆栈为空或者遇到左括号为止,然后将当前运算符入栈。

运算符栈:+ * ( -

后缀表达式列表:1 1 4 * 5 + 1 +

第十一次遍历到"4",发现堆栈顶部的运算符不是左括号 "(",将堆栈中的所有运算符弹出并加入后缀表达式列表中,直到堆栈为空或者遇到左括号为止,然后将当前运算符入栈。

运算符栈:+ * ( -

后缀表达式列表:1 1 4 * 5 + 1 + 4

第十二次遍历到")",发现将堆栈中的运算符弹出并加入后缀表达式列表中,直到遇到匹配的左括号为止,然后将左括号弹出,但不加入后缀表达式列表。

运算符栈:+ *

后缀表达式列表:1 1 4 * 5 + 1 + 4 -

所以后缀表达式为1 1 4 * 5 + 1 + 4 - * +

以下是代码

void mid_to_back(string s){
	int len=s.size();
	for(int i=0;i<len;i++){
		if(s[i]>='0'&&s[i]<='9') dat.push(s[i]);
		if(s[i]=='(') opt.push(s[i]);
		if(s[i]==')'){
			char t=opt.top();
			while(t!='('){
				opt.pop();
				dat.push(t);
				t=opt.top();
			}
			opt.pop();
		}
		if(change(s[i])>=1&&change(s[i])<=3){
			//print();
			if(!opt.empty()){
				char t=opt.top();
				while(!opt.empty()&&change(s[i])<=change(t)){
					if(change(s[i])==change(t)&&s[i]=='^') break;
					opt.pop();
					dat.push(t);
					if(!opt.empty()) t=opt.top();
				}
			}
			opt.push(s[i]);
		}
	}
	while(!opt.empty()){
		char t=opt.top();
		opt.pop();
		dat.push(t);
	}
	while(!dat.empty()){
		char t=dat.top();
		dat.pop();
		opt.push(t);
	}
	while(!opt.empty()){
		char t=opt.top();
		cout<<t<<' ';
		opt.pop();
		dat.push(t);
	}
	cout<<endl;
}
posted @ 2024-02-27 09:35  wuhupai  阅读(18)  评论(0编辑  收藏  举报