题目详情:
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+
、-
、*
、\
以及左右括号()
,表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
结尾无空行
输出样例:
2 3 7 4 - * + 8 4 / +
结尾无空行
作者:DS课程组;单位:浙江大学
代码长度限制:16 KB;时间限制:400 ms;内存限制:64 MB
———————————————————————————————————————————
这个题还比较《友好》,输入以字符串的形式给出。根据教材上的算法就“很好过了”。再列举一下加深印象:
1.运算数直接输出
2.左括号:压如栈中
3.右括号:从栈内输出运算符,知道左括号为止。(左括号也要弹出去)
4.运算符:优先级大于栈顶或为空,压入栈中。小于等于栈顶,弹出栈顶并输出,再比较。
5.输出栈中余留的符号。
按照上面的思路,很快就写出了代码。但是一个测试点都过不了。
中途我改了亿次代码,大部分都是过不了,或者只通过一个,我就不放出来丢人了。总结一下这道题有哪些坑点:
1.这道题的输出要求很特殊,每个单位空格隔开,但最后一个友不能有空格,大大的增加了输出难度。
在这里自己写一个打印函数:
void print(char ch)
{
len++; //全局变量,记录打印长度
if(len==n) cout<<ch; //长度与原来长度相同代表最后一个
else cout<<ch<<" ";
}
2.len的长度非常重要,特别是不输出时也要注意增加。
3. 对于一位的整数,我们可以一个一个的读,按照上面的函数输出。但是这道题的数有双位数甚至多位数,对于数字不能一个一个输出。对于数字的情况必须要整个输出,并且保证len的长度增加。
4.数字还会有小数的情况,不要忘了判断小数点。
5.最强AC拦路虎:”(“前面和算式最前面,遇到负数的话,要作为整体一起输出。
Code:
#include<iostream>
#include<ctype.h>
#include<string>
#include<stack>
using namespace std;
int len=0,n;
void trans(char &ch) //转换函数,为了比较优先级,赋予不同的值
{
if(ch=='+'||ch=='-') ch=1;
else if(ch=='*'||ch=='/') ch=2;
else ch=0; //括号降为最低级,应为左括号必须遇到右括号才输出
}
int cmp(char a,char b)
{
trans(a);
trans(b);
if(a>b) return 1;
if(a==b) return 0;
if(a<b) return -1;
}
void print(char ch)
{
len++;
if(len==n) cout<<ch;
else cout<<ch<<" ";
}
int main()
{
string s;
getline(cin,s);
n=s.size();
stack<char>opra;
for(int i=0;i<n;i++){
while(isdigit(s[i])||s[i]=='.'){
if(i+1<n&&(isdigit(s[i+1])||s[i+1]=='.')){
cout<<s[i];
++len;
} //长串数字不能用print输出
else print(s[i]);
++i;
if(i>=n) break;
}
if(i>=n) break;
if(s[i]=='(') opra.push(s[i]);
else if(s[i]==')'){
while(opra.top()!='('){
print(opra.top());
opra.pop();
}
opra.pop();
len+=2; //左右两个括号并没有输出,但是它存在于原字符,必须要将len+2
}
else{
if(i==0||(i>0&&s[i-1]=='(')){
if(s[i]=='-') cout<<s[i];
len++;
continue;
}//单独处理坑点5
while(!opra.empty()&&cmp(s[i],opra.top())<=0){
print(opra.top());
opra.pop();
}
opra.push(s[i]);
}
}
while(!opra.empty()){
print(opra.top());
opra.pop();
}
return 0;
}
运行结果:
看似很简单,其实很多坑。