中缀表达式转换为后缀表达式(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)

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • NFV概述_NFV技术

    NFV概述_NFV技术NFV(网络功能虚拟化)

  • Scrapy爬虫框架,入门案例(非常详细)「建议收藏」

    Scrapy爬虫框架,入门案例(非常详细)「建议收藏」Scrapy,Python开发的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试.其最初是为了页面抓取(更确切来说,网络抓取)所设计的,后台也应用在获取API所返回的数据(例如AmazonAssociatesWebServices)或者通用的网络爬虫.Scrapy吸引人的地…

  • 互联网100强公布_互联网排行榜

    互联网100强公布_互联网排行榜无意中翻看到一篇我在三年多前写的文章《我看中国互联网web2.0百强名单》,读来颇有感概。2005-2006那两年,正是WEB2.0概念轰轰烈烈的时候,大大小小的新网站层出不穷,博客、视频、交友、评点、社区、聚合……不管自己的网站的UGC比例多少,都宣传自己是WEB2.0,好像不贴上WEB2.0的标签,就不够潮流,不够IN,就吸引不了用户和风投。WEB2….

  • linux上查看mysql的密码_Linux下MySQL忘记密码「建议收藏」

    linux上查看mysql的密码_Linux下MySQL忘记密码「建议收藏」1、前沿今天在服务器安装mysql之后,登录发现密码错误,但是我没有设置密码呀,最后百度之后得知,mysql在5.7版本之后会自动创建一个初始密码。报错如下:[root@mytestlnx02~]#mysql-uroot-pEnterpassword:ERROR1045(28000):Accessdeniedforuser’root’@’localhost'(usingp…

  • 图片介质受写入保护_写入保护

    图片介质受写入保护_写入保护最近使用U盘,突然不能正常使用了,在U盘内新建文件夹,提示“介质受写入保护”无法创建文件,赶紧网上查找解决办法。查找的结果比解释比较全面的就是:方法一:格式化我的电脑(右击)-管理-磁盘管理-选中U盘右键删除后格式化(网上的方法,这招肯定能用,但是适用于没有重要数据的前提下,格式化后之前的数据会全部丢失)方法二:修改注册表1、打开注册表win+R(即开始-运行)键入regedit.exe2、进入如…

    2022年10月26日
  • cBridge 2.0测试网升级:全新的状态守卫者网络UI/UX[通俗易懂]

    cBridge 2.0测试网升级:全新的状态守卫者网络UI/UX[通俗易懂]今天,我们发布了cBridge2.0升级版测试网!

发表回复

您的电子邮箱地址不会被公开。

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