【C语言实现中缀转后缀】

中缀转后缀

运算符优先级:
( > ^ > * / > + - > )

^为幂运算,例如 x 3 x^3 x3
左括号(优先级最高,大于幂运算^,大于乘除 * \,大于加减+ -,右括号优先级最低,遇到右括号)时,弹出优先级大于等于右括号的所有运算符,即弹出(前的所有运算符以及左括号((左括号不存入postfix数组)
实现步骤

  1. 遇到操作数:直接存入postfix数组
  2. 遇到界限符:遇到(直接入栈,遇到),依次弹出栈内运算符并加入后缀表达式,直到遇见(为止,(不加入后缀表达式中
  3. 遇到运算符:若栈空直接加入,栈非空则先弹出栈内优先级大于或等于当前运算符的所有运算符,最后将当前运算符存入栈
  4. infix遍历结束后,若栈S非空,则依次弹出并存入postfix

我们以例子来帮助理解:
求中缀表达式12+3*5+(2+10)*5的后缀表达式:(运算符与操作数之间以空格隔开)

S栈(底 → \rightarrow 顶)postfix数组操作
12操作数直接存入postfix数组
+,12若栈空直接加入
+,12 3操作数直接存入postfix数组
+,*12 3+<*,栈顶不弹出
+,*12 3 5操作数直接存入postfix数组
+12 3 5 * +按顺序比较并弹出栈内所有 ≥ \geq 的运算符。* ≥ \geq +,+ ≥ \geq +。故都弹出,最后压入+
+,(12 3 5 * +遇到(直接入栈
+,(12 3 5 * + 2操作数直接存入postfix数组
+,(,+12 3 5 * + 2+<(,栈顶不弹出
+,(,+12 3 5 * + 2 10操作数直接存入postfix数组
+12 3 5 * + 2 10 +遇到),依次弹出栈内运算符并加入后缀表达式,直到遇见(为止,(不加入后缀表达式中
+,*12 3 5 * + 2 10 ++<*,栈顶不弹出
+,*12 3 5 * + 2 10 + 5操作数直接存入postfix数组
12 3 5 * + 2 10 + 5 * +栈S非空,则依次弹出并存入postfix

代码易错点
5. 处理负数与减号冲突的问题,用空格隔开,与数字无间隔的即为负数的符号,有间隔的为运算符减号
6. 输入数字不止一位,比如12,20,2003 。在for循环内用while解决,若当前字符与下一字符均为数字时,进入while循环,不断将字符读入postfix,直至下一字符不为数字跳出循环

输入样例1

4+2*3-10/5

输出结果

4 2 3 * + 10 5 / -

请添加图片描述

输入样例2

12+3*5+(2+10)*5

输出结果

12 3 5 * + 2 10 + 5 * +

请添加图片描述

代码实现

#include<bits/stdc++.h>
#define MaxSize 20
typedef struct S1 { //转换用
	char data[MaxSize] = {0};
	int top;
} SqStack;
void InitStack(SqStack &S) {
	S.top = -1;
}
void change(char infix[MaxSize], char postfix[MaxSize]) { //中缀转后缀
	SqStack S;
	InitStack(S);
	int i, j;
	for (i = 0, j = 0; i < strlen(infix); i++) {
		if (isdigit(infix[i])) { //若为操作数,直接存入
			while (isdigit(infix[i]))
				postfix[j++] = infix[i++];
			postfix[j++] = ' ';
		}
		if (infix[i] == '(') { //若为左界限符,存入栈
			S.data[++S.top] = infix[i]; //'('存
		}
		if (infix[i] == ')') { //若为右界限符,开始向右扫描
			while (S.data[S.top] != '(') {
				postfix[j++] = S.data[S.top--];
				postfix[j++] = ' ';
				if (S.data[S.top] == '(') { //'('不存
					S.top--;
					break;
				}
			}
		}
		if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/') { //若为运算符
			if (infix[i] == '+' || infix[i] == '-') {
				while (1) { //弹出优先级高于或等于当前运算符的所有运算符
					if (S.data[S.top] == '(' || S.top == -1) {
						break;
					}
					postfix[j++] = S.data[S.top--];
					postfix[j++] = ' ';
				}
				S.data[++S.top] = infix[i]; //最后存入当前运算符
			} else if (infix[i] == '*' || infix[i] == '/') {
				while (1) {
					if (S.data[S.top] == '(' || S.data[S.top] == '+' || S.data[S.top] == '-' || S.top == -1) {
						break;
					}
					postfix[j++] = S.data[S.top--]; //依次存入输出数组
					postfix[j++] = ' ';
				}
				S.data[++S.top] = infix[i]; //最后存入当前运算符
			}
		}
	}
	while (S.top != -1) {
		postfix[j++] = S.data[S.top--];
		postfix[j++]=' ';
	}
	for(int i=0;i<j;i++)
	printf("%c",postfix[i]);
}
int main() {
	float pre, last;
	char infix[MaxSize] = {0};
	char postfix[MaxSize] = {0};
	printf("请输入表达式: ");
	scanf("%s", infix);
	change(infix, postfix);
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快苏排序OAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值