表达式分为前缀,中缀,后缀,三种表达形式。两者之间的转换规则请参考这篇博客。
https://blog.csdn.net/Antineutrino/article/details/6763722 这里面详细讲述了,三者之间的转换关系,看完后可以掌握基本的表达式转换。
除去表达式转换的基本规则,个人认为表达式转换有以下三个难点:
1、小数没有办法表示和输出;
2、数字本身自带的负号难以表达和实现;
3、多位数字没有办法很好的去表达。
类如PTA 7-1这道题:
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
很多人(包括我自己,咳咳)在掌握了基本的转换规则后,仍然无法解决此题,很多问题就是出现在上面提到的三点,可以拿着三点出几组数据看看是否能卡死自己的代码。
在网上翻阅了很多的此类题的模板,在参考了这篇博客后表达式转换模板,精炼出了一套模板,在这里与大家分享.
AC代码(此代码通过了PTA的测试数据),代码有点长,希望大家耐心看完:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100;
char s[maxn];
int len;
bool judge(char c)
{
return c=='-'||c=='+';
}
bool judge1(char c)
{
return c=='(';
}
bool compare(char a,char b)//优先级的比较
{
if(a=='(') return 0;
if(b=='+'||b=='-') return 1;
else
{
if(a=='*'||a=='/') return 1;
else return 0;
}
}
void solve()
{
char mark[maxn];
int pos=0,flag=0;//flag用来控制中间空格的输出,主要是多位数字的输出
for(int i=0;i<len;i++)
{
if((s[i]>='0'&&s[i]<='9')||s[i]=='.')//若为数字直接输出,注意小数点的处理
{
if(flag) printf(" ");
printf("%c",s[i]);
flag=0;
}
else if(judge(s[i])&&(i ? judge1(s[i-1]) : 1 ))//判断负号是否为本身所有
{
if(s[i]=='-')
{
if(flag) printf(" ");
printf("%c",s[i]);
flag=0;
}
}
else//其余字符的按规则处理
{
if(pos)
{
if(s[i]=='(') mark[pos++]=s[i];
else if(s[i]==')')//对于左括号的处理
{
while(pos--)
{
if(mark[pos]=='(') break;
printf(" %c",mark[pos]);
}
}
else
{
while(pos)//对于优先级规则的处理
{
if(compare(mark[pos-1],s[i])) printf(" %c",mark[--pos]);//输出符号前必然有数字的输出,所以直接输出空格即可
else break;
}
mark[pos++]=s[i];
}
}
else mark[pos++]=s[i];//如果为空则直接压入
for(int j=0;j<pos;j++)//判断是否控制格式,主要是排除(、)对格式控制的影响
{
if(mark[j]!='(')
{
flag=1;
break;
}
}
}
}
while(pos)
{
printf(" %c",mark[--pos]);
}
}
int main()
{
scanf("%s",s);
len=strlen(s);
solve();
return 0;
}