这道题有很多坑!!!弄了好久!!!
7-20 表达式转换 (25分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
易错的地方!!
1.输出中有可能有小数
2.输入时有可能有多位数,在判断数字的时候需要用到一个while循环来判断是否为数字。
3.输入时有可能有负数,需要判断是正负号还是加减号。如果是正号,不用输出,是负号则要输出。(这个地方弄了好久)。如果是正负号,那么只可能在开头出现,或者是在左括号的后面出现。其余的±号就都为加减号了。
整体思路就是:
注意最后要将栈中剩余的符号全部出栈!!!
代码实现(c++):
#include<iostream>
#include<stack>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
bool compare(char pre,char cur)//比较现在的符号优先级是否低于栈顶元素
{//也就是判断是否要出栈 ,如果要出栈返回true
if(cur==')')
return true;
if(pre=='('||cur=='(')
return false;
if(cur=='+'||cur=='-')
return true;
else if(cur=='*'||cur=='/')
{
if(pre=='*'||pre=='/')
return true;
else if(pre=='+'||pre=='-')
return false;
}
}
int main()
{
stack<char> s;
string end;//用来存放整个后缀表达式
char c[25];
cin>>c;
for(int i=0;i<strlen(c);i++)
{
if((c[i]=='+'||c[i]=='-')&&(i==0||c[i-1]=='(')||isdigit(c[i]))//如果出现正负号(正负号只能出现在最开头,或者出现在左括号的后面)
{
if(i!='+')//如果是加号,则不用放入后缀表达式中,是减号或者数字则放入
{
end+=c[i];
}
i++;//记住这里要i++
while(i<strlen(c)&&((isdigit(c[i]))||c[i]=='.'))//如果是数字或者小数点
{
end+=c[i];
i++;
}
i--;//前面i多加了,这要减去
end+=' ';
}
else//如果是字符
{
if(s.empty() ==true||c[i]=='(')//如果栈空或者输入的为'(',就直接入栈
{
s.push(c[i]);
}
else
{
if(c[i]==')')//如果为右括号,那就将前面的符号全部出栈,直到出现左括号
{
while(!s.empty() &&s.top() !='(')
{
end+=s.top() ;
end+=' ';
s.pop() ;
}
s.pop() ;//左括号出栈
}
else
{
if(compare(s.top() ,c[i])==true)//如果c[i]的优先级低于s.top,那就出栈
{
while(!s.empty() &&compare(s.top() ,c[i])==true)
{
end+=s.top() ;
end+=' ';
s.pop() ;
}
s.push(c[i]); //记得其他的出栈之后要将这个符号存入
}
else//如果c[i]的优先级高于s.top,直接入栈
{
s.push(c[i]);
}
}
}
}
}
while(!s.empty() )//将栈中剩余字符全部出栈
{
end+=s.top() ;
end+=' ';
s.pop() ;
}
for(int i=0;i<end.size() -1;i++)//去掉最后一个空格输出
{
cout<<end[i];
}
}