PTA 数据结构 第二版 习题3.11 表达式转换 (25分)

1、问题

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。

输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。

输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。

输入样例:
2+3*(7-4)+8/4

输出样例:
2 3 7 4 - * + 8 4 / +

2、解决思路

中缀表达式a + b*c + (d * e + f) * g,其转换成后缀表达式则为a b c * + d e * f + g * +。

转换过程需要用到栈,具体过程如下:

1)如果遇到操作数,我们就直接将其输出。

2)如果遇到操作符,则我们将其放入到栈中,遇到左括号时我们也将其放入栈中。

3)如果遇到一个右括号,则将栈元素弹出,将弹出的操作符输出直到遇到左括号为止。注意,左括号只弹出并不输出。

4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,从栈中弹出元素直到遇到发现更低优先级的元素(或者栈为空)为止。弹出完这些元素后,才将遇到的操作符压入到栈中。有一点需要注意,只有在遇到" ) “的情况下我们才弹出” ( “,其他情况我们都不会弹出” ( "。

5)如果我们读到了输入的末尾,则将栈中所有元素依次弹出。

注意点

1、测试点3 运算数前有正负号

分两种情况:1、+ - 是第一个字符;2、+ - 出现在 ‘(’ 之后,则表示正负
陷阱:当+表示正负时,不予输出
测试用例:

输入:-2*(+2-2)
输出:-2 2 2 - *

3、我的代码

#include <stdio.h>
#include <stdlib.h>
char str[25];
char st[20];
int top=-1;
int main()
{
	gets(str);
	int len=0,count=0;//len是需要打印的字符的个数 ,count表示已打印的字符个数
	for(int i=0;str[i]!='\0';i++)
	{
		if(str[i]!='('&&str[i]!=')')
		len++;
	}
	for(int i=0;str[i]!='\0';i++)
	{
		if(str[i]=='(')
		{
			st[++top]=str[i];
		}	
		else if(str[i]=='*'||str[i]=='/')
		{
			while(top>-1&&(st[top]=='*'||st[top]=='/'))
			{
				printf("%c",st[top--]);
				count++;
				if(count!=len)
					printf(" ");
			}
			st[++top]=str[i];
		}
		else if(str[i]=='+'||str[i]=='-')
		{
			//以下情况表示正负
			if(i==0||(i>0&&str[i-1]=='(') )
			{
				+表示正负时无需打印
				if(str[i]=='+')
				{
					count++;//表示跳过 实际没打印 
				}
				else
				{
					printf("%c",str[i]);
					count++;
				} 
				continue;
			}
			while(top>-1&&st[top]!='(')
			{
				printf("%c",st[top--]);
				count++;
				if(count!=len)
					printf(" ");
			}
			st[++top]=str[i];
		}
		else if(str[i]==')')
		{
			while(st[top]!='(')
			{
				printf("%c",st[top--]);
				count++;
				if(count!=len)
					printf(" ");
			}
			top--;
		}
		else
		{
			printf("%c",str[i]);
			count++;
			if(count!=len&&(str[i+1]<'0'||str[i+1]>'9')&&str[i+1]!='.')
				printf(" ");
		}
	}	
	while(top!=-1)
	{
		printf("%c",st[top--]);
		count++;
		if(count!=len)
			printf(" ");
	}
	return 0;
} 

4、测试结果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值