【pta】7-20 表达式转换 (25 分) <中缀转后缀>
一、题目大意
题目链接:https://pintia.cn/problem-sets/15/problems/827
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
结尾无空行
输出样例:
2 3 7 4 - * + 8 4 / +
结尾无空行
二、第一版代码
#include <bits/stdc++.h> using namespace std; int main(void) { stack<char>st; string s; cin>>s; int flag=0; for (int i=0;i<s.size();i++) { if (s[i]>='0'&&s[i]<='9') { if (flag) { printf("%c",s[i]); flag=0; } else { if (i) printf(" "); printf("%c",s[i]); } } else if (st.empty()) { if (s[i]=='+'&&i==0) continue; else if (s[i]=='+'&&s[i-1]=='(') continue; else if (s[i]=='-'&&i==0) printf(" %c",s[i]),flag=1; else if (s[i]=='-'&&s[i-1]=='(') printf(" %c",s[i]),flag=1; else st.push(s[i]); } else if (s[i]=='*'||s[i]=='/') { if (st.top()=='+'||st.top()=='-'||st.top()=='(') st.push(s[i]); else { if (i) printf(" "); printf("%c",st.top()); st.pop(); st.push(s[i]); } } else if (s[i]=='+'||s[i]=='-') { if (s[i-1]=='(') { if (s[i]=='+') continue; else printf(" %c",s[i]); flag=1; continue; } while (st.top()!='+'&&st.top()!='-'&&st.top()!='(') { if (i) printf(" "); printf("%c",st.top()); st.pop(); } if (st.top()=='('||st.empty()) st.push(s[i]); else { if (i) printf(" "); printf("%c",st.top()); st.pop(); st.push(s[i]); } } else if (s[i]=='(') st.push(s[i]); else if (s[i]==')') { while (st.top()!='(') { if (i) printf(" "); printf("%c",st.top()); st.pop(); } st.pop(); } else if (s[i]=='.') { printf("%c",s[i]); flag=1; } } while (!st.empty()) { printf(" %c",st.top()); st.pop(); } return 0; }

当时的大无语事件
后来看到了大佬写的文章,大受震撼,好像确实有很多点都没考虑到(当时小数和负数都没想到)
https://blog.csdn.net/SiKongPop/article/details/77972879
后来改了一下终于ac
三、ac代码
#include <bits/stdc++.h> using namespace std; int main(void) { stack<char>st; string s; cin>>s; int flag=1; //第二个测试点的坑,(嵌套括号),这样任何情况第一个数字都会直接输出 for (int i=0;i<s.size();i++) { if (s[i]>='0'&&s[i]<='9') { if (flag) //遇到特殊情况,eg:0.5,-2 { printf("%c",s[i]); flag=0; continue; } if (s[i-1]<'0'||s[i-1]>'9') // eg:-25 { if (i) printf(" "); printf("%c",s[i]); } else if (s[i+1]>='0'&&s[i+1]<='9'||s[i-1]>='0'&&s[i-1]<='9') //eg:123 { printf("%c",s[i]); } } else if (st.empty()) { if (s[i]=='+'&&i==0) continue; //eg:+5*10 else if (s[i]=='-'&&i==0) printf("%c",s[i]),flag=1; //eg:-5+1 else st.push(s[i]); } else if (s[i]=='*'||s[i]=='/') { if (st.top()=='+'||st.top()=='-'||st.top()=='(') st.push(s[i]); //优先级高的推入 else { if (i) printf(" "); printf("%c",st.top()); st.pop(); st.push(s[i]); } } else if (s[i]=='+'||s[i]=='-') { if (s[i-1]=='(') { if (s[i]=='+') continue; //eg:(+5)+2 else { if (i) printf(" "); //eg:(-5+1)+2 printf("%c",s[i]); flag=1; continue; } } while (st.top()!='+'&&st.top()!='-'&&st.top()!='(') //直到栈内优先级和当前一样,或更低 { if (i) printf(" "); printf("%c",st.top()); st.pop(); } if (st.top()=='('||st.empty()) st.push(s[i]); //栈内优先级比当前低,或者栈空了 else { if (i) printf(" "); printf("%c",st.top()); //把栈顶的输出,并推入当前符号 st.pop(); st.push(s[i]); } } else if (s[i]=='(') st.push(s[i]); //栈内'('优先级最低,直接推入 else if (s[i]==')') //将栈顶元素输出并推出,直到找到'(' { while (st.top()!='(') { if (i) printf(" "); printf("%c",st.top()); st.pop(); } st.pop(); } else if (s[i]=='.') //判定小数部分 { printf("%c",s[i]); flag=1; } } while (!st.empty()) //将栈内剩余元素依次输出 { printf(" %c",st.top()); st.pop(); } return 0; }

注释写的挺详细了,这里不过多赘述,这道题按照知识点正常模拟即可
四、亿些知识点


何钦铭老师yyds
感谢所有大佬的文章思路和代码
peace

浙公网安备 33010602011771号