中缀表达式求值(P1175 表达式的转换)

思路:先中缀表达式转后缀,再对后缀表达式求值。

中缀表达式转后缀:O(n)扫一遍输入的中缀表达式:

1.遇到数:直接输出

2.遇到左括号:左括号直接入栈。

3.遇到运算符号:利用建立的符号栈,栈内总原则为高级运算压在低级运算之上。

4.遇到加、减、乘、除、乘方,按照正常的运算优先级处理(可以看一下P1981 表达式求值)。从栈顶开始,将运算优先级高于或等于待入栈符号的所有符号逐一出栈输出,直到遇到栈内优先级低于入栈符号的符号or左括号为止。

5.遇到右括号:持续进行出栈操作,输出运算符,直至遇到左括号。

扫完后,将符号栈内所有剩余符号出栈输出。这时输出的字符串便为输入的中缀表达式的后缀表达式。然后将后缀表达式直接进行运算即可。

AC代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int MAXN=105;
char charac[MAXN];//charac:中缀转后缀时用的运算符栈 
int totc;
char ss[MAXN];//ss:存储中缀表达式 
int first[MAXN],len;//first:运算符优先级
char last[MAXN];//last:存储后缀表达式  
int ans[MAXN],totl,cnt;//ans:求后缀表达式时存储数字 

int main()
{
	scanf("%s",ss+1);
	len=strlen(ss+1);
	first[40]=first[41]=first[94]=2,first[42]=first[47]=1;//制定优先级(first值大的运算优先级高) 
	for(int i=1;i<=len;i++)
	{
		if('0'<=ss[i]&&ss[i]<='9')	last[++cnt]=ss[i];//遇到数:直接输出
		
		if(ss[i]=='(')	charac[++totc]=ss[i];//遇到左括号:左括号直接入栈。
		
		if(ss[i]=='+'||ss[i]=='-'||ss[i]=='*'||ss[i]=='/'||ss[i]=='^')
		//遇到加、减、乘、除、乘方,按照正常的运算优先级处理。
		//从栈顶开始,将运算优先级高于或等于待入栈符号的所有符号逐一出栈输出,
		//直到遇到栈内优先级低于入栈符号的符号 or 左括号为止。
		//然后将当前运算符压入栈中 
		{
			while(totc>0&&first[(int)charac[totc]]>=first[(int)ss[i]])
			{
				if(charac[totc]=='(')	break;
				last[++cnt]=charac[totc];	totc--;
			}
			charac[++totc]=ss[i];
		}
		
		if(ss[i]==')')
		//遇到右括号:持续进行出栈操作,输出运算符,直至遇到左括号。
		{
			while(charac[totc]!='(')
			{
				last[++cnt]=(int)charac[totc];
				totc--;
			}
			totc--;//左括号只出栈不输出 
		}		
	}
	for(int i=totc;i>=1;i--)	last[++cnt]=charac[i];
	for(int i=1;i<=cnt;i++)	 cout<<last[i]<<" ";
	cout<<'\n';
	
	for(int i=1;i<=cnt;i++)//对后缀表达式求值 
	{
		if('0'<=last[i]&&last[i]<='9')	 ans[++totl]=last[i]-'0';
		if(last[i]<'0'||last[i]>'9')
		{
			if(last[i]=='+')	ans[totl-1]+=ans[totl];
			if(last[i]=='-')	ans[totl-1]-=ans[totl];
			if(last[i]=='*')	ans[totl-1]*=ans[totl];
			if(last[i]=='/')	ans[totl-1]/=ans[totl];
			if(last[i]=='^')
			{
				int temp=ans[totl-1];
				for(int j=1;j<=ans[totl]-1;j++)	 ans[totl-1]*=temp;
			}
			totl--;
			for(int j=1;j<=totl;j++)	cout<<ans[j]<<" ";
			for(int j=i+1;j<=cnt;j++)	 cout<<last[j]<<" ";
			cout<<'\n';	
		}
	}	

	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,数据结构中的和队列可以用来实现中缀表达式求值算法。中缀表达式是我们最为常见的表达式,运算符号位于参与运算的两个操作数中间的表达式称作中缀表达式中缀表达式的求值算法可以通过将中缀表达式转换为后缀表达式,然后再利用来实现后缀表达式的求值。具体步骤如下: 1. 将中缀表达式转换为后缀表达式。可以使用来实现,具体步骤如下: a. 从左到右遍历中缀表达式的每个元素。 b. 如果当前元素是操作数,则将其输出到后缀表达式中。 c. 如果当前元素是左括号,则将其压入中。 d. 如果当前元素是右括号,则将中的元素弹出并输出到后缀表达式中,直到遇到左括号为止。 e. 如果当前元素是运算符,则将其与顶元素进行比较,如果顶元素优先级高于当前元素,则将顶元素弹出并输出到后缀表达式中,直到顶元素优先级低于或等于当前元素为止,然后将当前元素压入中。 f. 重复步骤a到e,直到遍历完中缀表达式。 2. 利用来实现后缀表达式的求值。具体步骤如下: a. 从左到右遍历后缀表达式的每个元素。 b. 如果当前元素是操作数,则将其压入中。 c. 如果当前元素是运算符,则将顶的两个元素弹出,进行运算,并将结果压入中。 d. 重复步骤a到c,直到遍历完后缀表达式。 e. 中最后剩下的元素即为后缀表达式的求值结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值