表达式转换【PAT】

34 篇文章 0 订阅
28 篇文章 0 订阅

3-06. 表达式转换

时间限制  
400 ms
内存限制  
32000 kB
代码长度限制  
8000 B
判题程序    
Standard    

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

输入格式说明:

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

输出格式说明:

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

样例输入与输出:

序号输入输出
1
2+3*(7-4)+8/4
2 3 7 4 - * + 8 4 / +
2
((2+3)*4-(8+2))/5
2 3 + 4 * 8 2 + - 5 /
3
1314+25.5*12
1314 25.5 12 * +
4
-2*(+3)
-2 3 *
5
123
123

 

#include<iostream>
#include<stack>
#include<string.h>
using namespace std;

stack<char> s;
int Judge(char a)
{
	if((a=='+')||(a=='-')||(a=='*')||(a=='/')||(a=='(')||(a==')')) return 1;
	
	return 0;
	
}

int Judge_(char b,char a)
{
    if(b=='+'||b=='-')
		if((a=='+')||(a=='-')||(a=='*')||(a=='/')||(a=='(')) return 1; 
		
		return 0;
		
}

int Judge_jjcc(char a)
{
	if((a=='+')||(a=='-')||(a=='*')||(a=='/')) return 1; 
		
		return 0;

}

int Judge_jj(char a)
{
	if((a=='+')||(a=='-')) return 1; 
		
		return 0;

}

int premer(char a,char b)
{
	switch(a)
	{
	case '+':
		{
			switch(b)
			{
			case '+':return 0;break;
			case '-':return 0;break;
			case '*':return 0;break;
			case '/':return 0;break;
			case '(':return 0;break;
				
			}
			
		}break;
	case'-':
		{
			switch(b)
			{
			case '+':return 0;break;
			case '-':return 0;break;
			case '*':return 0;break;
			case '/':return 0;break;
			case '(':return 0;break;
				
			}
			
		}break;
	case '*':
		{
			switch(b)
			{
			case '+':return 1;break;
			case '-':return 1;break;
			case '*':return 0;break;
			case '/':return 0;break;
			case '(':return 0;break;
				
			}
			
		}break;
	case'/':
		{
			switch(b)
			{
			case '+':return 1;break;
			case '-':return 1;break;
			case '*':return 0;break;
			case '/':return 0;break;
			case '(':return 0;break;
				
			}
			
		}break;
	case'(':
		{
			switch(b)
			{
			case '+':return 0;break;
			case '-':return 0;break;
			case '*':return 0;break;
			case '/':return 0;break;
			case '(':return 0;break;
				
			}
			
		}break;
	default:break;
		
	}
	
}

int main()
{
	
	char a[30];
	scanf("%s",a);
	int len=strlen(a);
	int con_flag=0;
	int op_flag=1;
	bool first=false;

	for(int i=0;i<len;i++)
	{
		if(Judge(a[i])&&(!(i==0&&Judge_jj(a[i])))&&(!Judge_(a[i],a[i-1]))) //正常符号
		{

			if(a[i]==')')
			{
				while(s.top()!='(')
				{
					char temp=s.top();
					s.pop();
					cout<<" "<<temp;
				}
				s.pop();

				while(!s.empty()&&s.top()!='(')
				{
				  char temp_t=s.top();
				  s.pop();
				  cout<<" "<<temp_t;
				}
				
			}
			else if(!s.empty()&&(a[i]!='('))
			{
				if(premer(s.top(),a[i])) con_flag=1;
				else con_flag=0;
				while(con_flag)//压入的操作符优先级要大于顶部元素
				{
					char temp2=s.top();
					cout<<" "<<temp2;
					s.pop();
					if(!s.empty()) 
					{
						if(premer(s.top(),a[i])) con_flag=1;
						else con_flag=0;
					}
					else con_flag=0;
				}
				s.push(a[i]);
			}
			else s.push(a[i]);
			
			if(first==false&&Judge_jjcc(a[i]))
			{
				 first=true; cout<<" "; 
			}
			
			
		}
		else if(a[i]=='+'||a[i]=='-')//表示数据的正负
		{
			
			if(a[i]=='-') op_flag*=-1; //是-号 后面的数字乘以-1;
			//否则忽略
			first=true;
		}
		else 
		{  if(i==0)
		{
			cout<<a[i];
		}
		else 
		{
			if(op_flag==-1) {
                
				cout<<'-'<<a[i];
				op_flag=1;
				
			}
			else cout<<a[i];
			first=false;//遇到数字
			
		}
		
		}
		
	}
	while(!s.empty())
	{
		cout<<" "<<s.top();
		s.pop();
		
	}
	//printf("%s",a);
	system("pause");
	return 0;
}

解题报告:

对于取进来的字符可以分成3种情况

【1】正常操作符 表示运算关系

【2】正负号 表示数据的正负 如+2*(-2) 注意:本题中+号表示数据的正负时不输出 所以只要考虑‘-’的情况

【3】正常数字


【特殊情况】:判断第一个字符,之所以要考虑第一个字符是因为在字符a[i]的情况下判断情况【2】的状态时要查看a[i-1],如果是第一个字符 i=0,且a[i]=='+'或者a[i]=='-'归到【2】,如果是数字归到【3】,如果是正常操作符归到【1】。

 

输出格式考虑:考虑一种特殊情况,1234···连续的数字。思路:第一次碰到【1】正常操作符入队列的时候输出一个空格。每次弹出操作符都先输出一个空格。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值