前缀表达式后缀表达式_【数据结构】栈的应用-将中缀表达式转化为后缀(前缀)表达式...

本文介绍了如何使用栈将中缀表达式转换为后缀表达式,详细阐述了算法思想和过程分析,包括遇到括号、运算符和数字时的操作,并提供了一个具体的示例,最终得出后缀表达式AB+C*EF--。
摘要由CSDN通过智能技术生成

47064672f34cafe1a2b72f28c0634489.png

在表达式求值的过程中,常用到将中缀表达式转化为后缀表达式前缀表达式的过程

我们常见的表达式形式为中缀表达式,对于简单的中缀表达式可以很容易转化为前缀表达式或后缀表达式

例如,中缀表达式a+b,其前缀表达式为+ab,后缀表达式为ab+

较复杂的表达式则不易直接得出结果,这里我们将通过来实现相应的转化

示例表达式:[(A+B)*C]-[E-F]

转化为前缀表达式:

  1. 先计算A+B,转化为+AB
  2. +AB作为整体与C运算,转化为*+ABC
  3. 运算E-F,转化为-EF
  4. 将*+ABC与E-F都作为整体执行-运算,转化为-*+ABC-EF

转化为后缀表达式:

  1. 先计算A+B,转化为AB+
  2. AB+作为整体与C运算,转化为AB+C*
  3. 运算E-F,转化为EF-
  4. 将AB+C*与EF-作为整体执行-运算,转化为AB+C*EF--

用栈实现中缀表达式转化为后缀表达式

算法思想

如果检测到数字,则直接加入到后缀表达式中

如果检测到运算符时:

  1. 若为‘(’,入栈
  2. 若为‘)’,则依次将栈中的运算符加入后缀表达式,直到出现‘(’,并从栈中删除‘(’
  3. 若为‘+’,‘-’,‘*’,‘/’
  • 栈空,入栈
  • 栈顶元素为‘(’,入栈
  • 高于栈顶元素优先级,入栈
  • 否则,依次弹出栈顶运算符,直到一个优先级比它低的运算符或‘(’为止

遍历完成,若栈非空,依次弹出栈中所有元素

该算法使得栈顶运算符处于较高优先级,并先弹出栈,进入后缀表达式

过程分析

示例:((A+B)*C)-(E-F)

1.连续两个'(',入栈

(当前后缀表达式: )

3336a7c2aea356b0a7223c07c3141117.png
前缀表达式遍历进度((

2.遍历到数字A,加入到后缀表达式

(当前后缀表达式:A)

42f61d4102e86faf44844c7b10800fc4.png
前缀表达式遍历进度((A

3.遍历到运算符+,由于栈顶元素为‘(’,直接入栈。

(当前后缀表达式:A)

4.接着遍历数字B,加入到后缀表达式

(当前后缀表达式:AB)

3a958f93dac186546ad637dc3e60f839.png
前缀表达式遍历进度((A+B

5.遍历‘)’,依次将栈中的运算符加入后缀表达式,直到出现‘(’,并删除栈顶的‘(’

(当前后缀表达式:AB+)

注:括号是不会出现在后缀表达式或前缀表达式中的

d238615928ff78121d24703de4ffc488.png
前缀表达式遍历进度((A+B)

6.遍历到*,栈顶为‘(’,直接入栈

7.接着遍历数字C,直接加入到后缀表达式中

(当前后缀表达式:AB+C)

614f061b70b47d5367022c5dd85d7a46.png
前缀表达式遍历进度((A+B)*C

8.继续遍历到‘)’,依次将栈中的运算符加入后缀表达式,直到出现‘(’,并删除栈顶的‘(’

【当前后缀表达式:AB+C*】

c5774aacf367cd5e7c243da5acdc5db3.png
前缀表达式遍历进度((A+B)*C)

9.接着遍历到-,栈空,入栈

【当前后缀表达式:AB+C*】

ed13a0d57fe77e48f36a21bc79d50672.png
前缀表达式遍历进度((A+B)*C)-

10.遍历‘(’,直接入栈

【当前后缀表达式:AB+C*】

a411bc8d849bbab887f3372045f7a100.png
前缀表达式遍历进度((A+B)*C)-(

11.遍历到数字E,直接加入到后缀表达式

【当前后缀表达式:AB+C*E】

12.遍历到-,栈顶元素为‘(’,入栈

【当前后缀表达式:AB+C*E】

13.遍历到F,加入到后缀表达式

【当前后缀表达式:AB+C*EF】

2a6131a9c69246ab0969f0c1af09807d.png
前缀表达式遍历进度((A+B)*C)-(E-F

14.遍历到‘)’,依次将栈中的运算符加入后缀表达式,直到出现‘(’,并删除栈顶的‘(’

【当前后缀表达式:AB+C*EF-】

75a77ee86cf4067a2b976c2e115909a8.png
前缀表达式遍历进度((A+B)*C)-(E-F)遍历完毕

15.遍历完毕,栈非空,将栈中元素依次弹出

【当前后缀表达式:AB+C*EF--】

436085cc569720a657841234717decb0.png

成功得到后缀表达式!!!

代码实现

#include<stdio.h>

#define ElemType char
#define MaxSize 50

typedef struct {
	ElemType data[MaxSize];
	int top;
}SqStack;

void initStack(SqStack& S)
{
	S.top = -1;   //初始化栈顶指针
}

bool StackEmpty(SqStack S)
{
	if (S.top == -1)   //栈空
		return true;
	else
		return false;  //栈不空
}

bool Push(SqStack& S, ElemType x)
{
	if (S.top == MaxSize - 1)      //栈满 不能执行入栈操作
		return false;
	S.top++;                      //指针先加1,再入栈
	S.data[S.top] = x;
	return true;
}

bool Pop(SqStack& S, ElemType& x)
{
	if (S.top == -1)              //栈空 不能执行出栈操作
		return false;
	x = S.data[S.top];            //先出栈 指针再减1
	S.top--;
	return true;
}

bool GetPop(SqStack S, ElemType& x)
{
	if (S.top == -1)            //栈空报错
		return false;
	x = S.data[S.top];          //用x存储栈顶元素
	return true;
}

int main()
{
	SqStack S;
	initStack(S);

	char NifixExpression[] = { '(','(','A','+','B',')','*','C',')','-','(','E','-','F',')','0' };
	char PostfixExpression[60];    //在字符数组最后添加'0',作为结束标志
	int index = 0;
	char* p = NifixExpression;
	while (*p!='0')
	{
		if (*p == '(')         //如果为左括号,直接入栈
		{
			Push(S, *p);
			p++;
		}
		else if (*p == ')')//若为右括号,依次弹出栈中运算符,直到'(',并删除'('--用出栈不保存数据实现
		{
			while (S.data[S.top] != '(')
			{
				char temp;
				Pop(S, temp);
				if (temp == '+' || temp == '-' || temp == '*' || temp == '/')
				{
					PostfixExpression[index] = temp;
					index++;
				}
			}
			char temp;
			Pop(S, temp);     //把左括号也出栈
			p++;
		}
		else if (*p >= 'A' && *p <= 'Z') //这里用大写字母代替表达式中的数字,为大写字母则直接进入后缀表达式
		{
			PostfixExpression[index] = *p;
			index++;
			p++;
		}
		else
		{
			if (*p == '+' || *p == '-')
			{
				if (S.data[S.top] == '('||StackEmpty)//如果遍历到'+''-',且栈为空或栈顶为'(',直接入栈
				{
					Push(S, *p);
					p++;
				}
				else {
					while (S.data[S.top] != '('&&!StackEmpty)//依次弹出较高优先级运算符,直到'('
					{
						char temp;
						Pop(S, temp);
						PostfixExpression[index] = temp;
						index++;
					}
				}
			}
			else
			{
				Push(S, *p);
				p++;
			}
		}
	}
	if (!StackEmpty(S))          //若栈不为空,依次弹出其中的运算符
	{
		while (S.top != -1)
		{
			char temp;
			Pop(S,temp);
			PostfixExpression[index] = temp;
			index++;
		}
	}
	PostfixExpression[index] = '0';         //在字符数组后加'0',作为结束标志
	printf("中缀表达式为:%s",NifixExpression);
	printf("n");
	printf("后缀表达式为:%s", PostfixExpression);
	
	
}

测试结果

76a753d278e4b20376725ecc64f8a093.png

Bingo~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
不好意思,我看到你的问题是一样的,我之前回答的是解决中缀表达式后缀表达式的问题,如果你想了解如何用解决中缀表达式前缀表达式,可以参考以下思路: 1. 将中缀表达式倒序。 2. 将倒序后的中缀表达式中的左右括号互换。 3. 从右往左遍历倒序后的中缀表达式的每个元素。 4. 如果遇到操作数,直接输出。 5. 如果遇到右括号或运算符,将其压入中。 6. 如果遇到左括号,将中的元素依次弹出并输出,直到遇到右括号或运算符为止。将弹出的元素倒序输出。 7. 遍历完倒序后的中缀表达式后,将中剩余的元素依次弹出并输出。 8. 将输出的前缀表达式倒序即为原始中缀表达式前缀表达式。 代码实现如下: ```c++ #include <iostream> #include <stack> #include <algorithm> using namespace std; int priority(char c) // 定义运算符优先级 { if (c == '+' || c == '-') return 1; if (c == '*' || c == '/') return 2; return 0; } void infixToPrefix(string infix) // 中缀表达式前缀表达式 { reverse(infix.begin(), infix.end()); // 将中缀表达式倒序 stack<char> s; for (int i = 0; i < infix.length(); i++) { char c = infix[i]; if (isdigit(c)) cout << c; // 遇到操作数 else if (c == ')') s.push(c); // 遇到右括号 else if (c == '(') { // 遇到左括号 while (!s.empty() && s.top() != ')') { cout << s.top(); s.pop(); } s.pop(); // 弹出右括号 } else { // 遇到运算符 while (!s.empty() && priority(s.top()) >= priority(c)) { cout << s.top(); s.pop(); } s.push(c); } } while (!s.empty()) { // 将中剩余元素输出 cout << s.top(); s.pop(); } reverse(infix.begin(), infix.end()); // 将输出的前缀表达式倒序 } int main() { string infix = "1+2*(3-4)/5"; infixToPrefix(infix); return 0; } ``` 输出结果为:`+/1/*2-345`,即为换后的前缀表达式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值