中缀表达式转换为后缀表达式(C语言代码+详解)

中缀表达式转换为后缀表达式(C语言代码+详解)中缀表达式转换为后缀表达式1.创建栈2.从左向右顺序获取中缀表达式a.数字直接输出b.运算符情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出。情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个…

大家好,又见面了,我是你们的朋友全栈君。

中缀表达式转换为后缀表达式(思路)

1.创建栈
2.从左向右顺序获取中缀表达式

a.数字直接输出
b.运算符
情况一:遇到左括号直接入栈,遇到右括号将栈中左括号之后入栈的运算符全部弹栈输出,同时左括号出栈但是不输出

情况二:遇到乘号和除号直接入栈,直到遇到优先级比它更低的运算符,依次弹栈。

情况三:遇到加号和减号,如果此时栈空,则直接入栈,否则,将栈中优先级高的运算符依次弹栈(注意:加号和减号属于同一个优先级,所以也依次弹栈)直到栈空或则遇到左括号为止,停止弹栈。(因为左括号要匹配右括号时才弹出)。

情况四:获取完后,将栈中剩余的运算符号依次弹栈输出

例:比如将:2*(9+6/3-5)+4转化为后缀表达式 2 9 6 3 / +5 – * 4 +

在这里插入图片描述
转换算法代码如下:

/*中缀转后缀函数*/
void Change(SqStack *S,Elemtype str[])
{
	int i=0;
	Elemtype e;
	InitStack(S);
	while(str[i]!='\0')
	{
		while(isdigit(str[i])) 
		{/*过滤数字字符,直接输出,直到下一位不是数字字符打印空格跳出循环 */
			printf("%c",str[i++]);
			if(!isdigit(str[i]))
			{
				printf(" ");
			}
		}
		/*加减运算符优先级最低,如果栈顶元素为空则直接入栈,否则将栈中存储
		的运算符全部弹栈,如果遇到左括号则停止,将弹出的左括号从新压栈,因为左
		括号要和又括号匹配时弹出,这个后面单独讨论。弹出后将优先级低的运算符压入栈中*/
		if(str[i]=='+'||str[i]=='-')
		{
			if(!StackLength(S))
			{
				PushStack(S,str[i]);
			}
			else
			{
				do
				{
					PopStack(S,&e);
					if(e=='(')
					{
						PushStack(S,e);
					}
					else
					{
						printf("%c ",e);
					}
				}while( StackLength(S) && e != '(' );
				
				PushStack(S,str[i]);
			}
		}
		/*当遇到右括号是,把括号里剩余的运算符弹出,直到匹配到左括号为止
		左括号只弹出不打印(右括号也不压栈)*/
		else if(str[i]==')')
		{
			PopStack(S,&e);
			while(e!='(')
			{
				printf("%c ",e);
				PopStack(S,&e);
			}
		}
		/*乘、除、左括号都是优先级高的,直接压栈*/
		else if(str[i]=='*'||str[i]=='/'||str[i]=='(')
		{
			PushStack(S,str[i]);
		}
		
		else if(str[i]=='\0')
		{
			break;
		}
		
		else
		{
			printf("\n输入格式错误!\n");
			return ;
		}
		i++;
	}
	/*最后把栈中剩余的运算符依次弹栈打印*/
	while(StackLength(S))
	{
		PopStack(S,&e);
		printf("%c ",e);
	}
}

完整代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<ctype.h> 
#include<assert.h>

#define INITSIZE  20
#define INCREMENT 10
#define MAXBUFFER 20
#define LEN  sizeof(Elemtype)

/*栈的动态分配存储结构*/ 
typedef char Elemtype;
typedef struct{
	Elemtype *base;
	Elemtype *top;
	int StackSize;
}SqStack;

/*初始化栈*/
void InitStack(SqStack *S)
{
	S->base=(Elemtype*)malloc(LEN*INITSIZE);
	assert(S->base !=NULL);
	S->top=S->base;
	S->StackSize=INITSIZE;
}

/*压栈操作*/ 
void PushStack(SqStack *S,Elemtype c)
{
	if(S->top - S->base >= S->StackSize)
	{
		S->base=(Elemtype*)realloc(S->base,LEN*(S->StackSize+INCREMENT));
		assert(S->base !=NULL);
		S->top =S->base+S->StackSize;
		S->StackSize+=INCREMENT;
	}
	*S->top++ = c;
}
/*求栈长*/
int StackLength(SqStack *S)
{
	return (S->top - S->base);
}
/*弹栈操作*/
int PopStack(SqStack *S,Elemtype *c)
{
	if(!StackLength(S))
	{
		return 0;
	}
	*c=*--S->top;
	return 1;
}

/*中缀转后缀函数*/
void Change(SqStack *S,Elemtype str[])
{
	int i=0;
	Elemtype e;
	InitStack(S);
	while(str[i]!='\0')
	{
		while(isdigit(str[i])) 
		{/*过滤数字字符,直接输出,直到下一位不是数字字符打印空格跳出循环 */
			printf("%c",str[i++]);
			if(!isdigit(str[i]))
			{
				printf(" ");
			}
		}
		/*加减运算符优先级最低,如果栈顶元素为空则直接入栈,否则将栈中存储
		的运算符全部弹栈,如果遇到左括号则停止,将弹出的左括号从新压栈,因为左
		括号要和又括号匹配时弹出,这个后面单独讨论。弹出后将优先级低的运算符压入栈中*/
		if(str[i]=='+'||str[i]=='-')
		{
			if(!StackLength(S))
			{
				PushStack(S,str[i]);
			}
			else
			{
				do
				{
					PopStack(S,&e);
					if(e=='(')
					{
						PushStack(S,e);
					}
					else
					{
						printf("%c ",e);
					}
				}while( StackLength(S) && e != '(' );
				
				PushStack(S,str[i]);
			}
		}
		/*当遇到右括号是,把括号里剩余的运算符弹出,直到匹配到左括号为止
		左括号只弹出不打印(右括号也不压栈)*/
		else if(str[i]==')')
		{
			PopStack(S,&e);
			while(e!='(')
			{
				printf("%c ",e);
				PopStack(S,&e);
			}
		}
		/*乘、除、左括号都是优先级高的,直接压栈*/
		else if(str[i]=='*'||str[i]=='/'||str[i]=='(')
		{
			PushStack(S,str[i]);
		}
		
		else if(str[i]=='\0')
		{
			break;
		}
		
		else
		{
			printf("\n输入格式错误!\n");
			return ;
		}
		i++;
	}
	/*最后把栈中剩余的运算符依次弹栈打印*/
	while(StackLength(S))
	{
		PopStack(S,&e);
		printf("%c ",e);
	}
}

int main()
{
	Elemtype str[MAXBUFFER];
	SqStack S;
	gets(str);
	Change(&S,str);
	return 0;
}

运行效果截图如下:
在这里插入图片描述

如何实现将中缀表达式转换成后缀表达式后计算值

(https://blog.csdn.net/qq_42552533/article/details/86562791)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/148663.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ❤ 挑战C站最强C++ STL标准库总结(内含大量示例)

    ❤ 挑战C站最强C++ STL标准库总结(内含大量示例)前言最近博主为了准备七月份的百度之星的算法比赛,把C++STL的相关语法又重新学习了一遍,然后整理成此文,本文内含string、vector、deque、stack、queue、list、set、map共9种容器的概念及常用操作语法,以及对STL的遍历、查找、排序、替换、算术生成等常用算法的用法和示例,供读者阅读收藏,学习参考。给大家推荐博主本人学习过的一个c++STL质量极高的课程链接:C++进阶之STL,很适合0基础想快速入门C++STL的朋友,关于想进阶的朋友,可以去看候捷老师的C++S

    2022年7月18日
    15
  • 多线程处理mq消息_实现多线程有几种方式

    多线程处理mq消息_实现多线程有几种方式何为CMQ?腾讯云消息队列(CloudMessageQueue,CMQ)是一种分布式消息队列服务,它能够提供可靠的基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)之间的收发消息,存储在可靠有效的CMQ队列中,防止消息丢失。CMQ支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。——来源以及更多内容推荐看官方文档。…

    2025年7月8日
    4
  • 安卓 使用Gradle生成正式签名apk文件「建议收藏」

    安卓 使用Gradle生成正式签名apk文件

    2022年3月2日
    39
  • 分布式事务解决方案之TCC(Hmily)「建议收藏」

    分布式事务解决方案之TCC(Hmily)「建议收藏」1什么是TCC事务TCC是Try、Confirm、Cancel三个词语的缩写,TCC要求每个分支事务实现三个操作:预处理Try、确认Confirm、撤销Cancel。Try操作做业务检查及资源预留,Confirm做业务确认操作,Cancel实现一个与Try相反的操作即回滚操作。TM首先发起所有的分支事务的try操作,任何一个分支事务的try操作执行失败,TM将会发起所有分支事务的Cancel操作,若try操作全部成功,TM将会发起所有分支事务的Confirm操作,其中Confirm/Cancel操作若执

    2022年5月11日
    40
  • ap调试教程_超声波发生器说明书

    ap调试教程_超声波发生器说明书前言:在传统APA自动泊车系统中,通常使用超声波雷达进行车辆前后辈避障以及侧向车位探测。目前市场上大多数带有自动泊车功能的车辆均配有12个超声波雷达,本文从硬件安装及超声波雷达调试标定两方面对自动泊车超声波雷达的安装调试进行说明1硬件安装自动泊车配置的超声波雷达一般为两组12个雷达探头。单组6个雷达探头串联,其中第1和第6号雷达为长距LRU雷达,2-4号为短距SRU避障雷达。超声探头均…

    2025年10月26日
    2
  • linux命令启动MySQL

    linux命令启动MySQL====================================可使用如下命令启动MySQL:servicemysqldstart或者使用如下命令:/etc/init.d/mysqldstart可使用如下命令重新启动MySQL:servicemysqldrestart或者使用如下命令:/etc/init.d/mysqldrestart====…

    2022年5月11日
    41

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号