Description
表达式有三种表示方法,分别为:
- 前缀表示(波兰式):运算符+操作数1+操作数2
- 中缀表示:操作数1+运算符+操作数2
- 后缀表示(逆波兰式):操作数1+操作数2+运算符
例如:a +b * (c -d ) - e/f
- 波兰式:
-+a*b-cd/ef
(运算符在操作数的前面,用递归计算波兰式) - 中缀式:
a+b*c-d-e/f
- 逆波兰式:
abcd-*+ef/-
(运算符在操作数的后面,用栈计算逆波兰式)
中缀表示就是原表达式去掉括号。
根据表达式求波兰式、逆波兰式都是教材第三章表达式求值的思想。
求波兰式,需要操作数栈(注意不是计算结果入栈,计算式入栈),运算符栈。区别在于从后往前扫描表达式,(
换成 )
。栈顶运算符优先级>
新读入运算符优先级出栈,教材第三章表3.1中的相同运算符优先级>
(从左往右计算)改为<
,例如栈顶为+
,新读入的为+
,则栈顶优先级<
新读入的优先级。
求逆波兰式,只需要运算符栈。操作数直接输出,操作符按表3.1优先级顺序出栈,输出。
输入表达式,求其波兰式和逆波兰式。
Input
测试次数
每组测试数据一行,一个合法表达式
Output
对每组测试数据,输出两行
第一行,表达式的波兰表示
第二行,表达式的逆波兰表示
不同组测试数据间以空行分隔。
样例:
答案:
#include<iostream>
#include<stack>
#include<string>
#include<vector>
using namespace std;
vector<string> qianzhui(string s1){
//前缀
stack<char> sc1;
string temp1;
vector<string> ans;
//前缀式,从后往前输入进行判断
for (int i = s1.length()-1; i>=0; i--){
//获取数字然后放入最终答案
temp1 = "";
while(s1[i]>= '0'&&s1[i]<= '9'){
temp1 = s1[i--] + temp1;
}
if(!temp1.empty()){ //判断是否非空,避免传入空项
ans.push_back(temp1);
}
//出现括号,则将括号内式子递归到本函数一次获得式子,再输出到最终答案
if(s1[i] == ')'){
i--;
temp1 = "";
while(s1[i]!='('){
temp1 = s1[i--] + temp1;
}
vector<string> re1 = qianzhui(temp1);
for (auto it = re1.begin(); it != re1.end(); it++) //输出到最终答案
{
ans.push_back(*it);
}
continue;
}
//碰到运算符,进行运算符优先级比较
while (s1[i] == '+' || s1[i] == '-' || s1[i] == '*' || s1[i] == '/')
{
if (sc1.empty()) //如果是空栈,无需比较,直接放入栈
{
sc1.push(s1[i]);
break;
}
if( ( sc1.top()=='/' || sc1.top()=='*' ) && ( s1[i]=='+' || s1[i]=='-' ) ) //如果后面的运算符优先级高于前面的运算符,则直接输出目前数据到最终答案
{
//获取数字然后放入最终答案
temp1 = "";
temp1.append(1, sc1.top());
ans.push_back(temp1);
sc1.pop();
}else{ //否则运算符进栈
sc1.push(s1[i]);
break;
}
}
}
while (!sc1.empty()) //将栈中的操作符传入输出数组
{
temp1 = "";
temp1.append(1, sc1.top());
ans.push_back(temp1);
sc1.pop();
}
return ans;
}
vector<string> houzhui(string s2){
//后缀
stack<char> sc2;
string temp2;
vector<string> ans;
//前缀式,从前往后输入进行判断
for (int i = 0; i<s2.length(); i++){
//获取数字然后放入最终答案
temp2 = "";
while(s2[i]>= '0'&&s2[i]<= '9'){
temp2 = temp2 + s2[i++];
}
if(!temp2.empty()){ //判断是否非空,避免传入空项
ans.push_back(temp2);
}
//出现括号,则将括号内式子递归一次获得式子,再输出到最终答案
if(s2[i] == '('){
i++;
temp2 = "";
while(s2[i]!=')'){
temp2 = temp2 + s2[i++];
}
vector<string> re2 = houzhui(temp2);
for (auto it = re2.begin(); it != re2.end(); it++) //输出
{
ans.push_back(*it);
}
continue;
}
//碰到运算符,进行运算符优先级比较
while (s2[i] == '+' || s2[i] == '-' || s2[i] == '*' || s2[i] == '/')
{
if (
(sc2.empty()) ||
(
(s2[i] == '*' && !sc2.empty()) ||
(s2[i] == '/' && !sc2.empty()) ||
(s2[i] == '+' && (sc2.top() == '-' || sc2.top() == '+')) ||
(s2[i] == '-' && (sc2.top() == '+' || sc2.top() == '-'))
)
)//如果栈为空,或后面的运算符文高于或等于前面运算符的优先级,就将后面的运算符压入栈中
{
sc2.push(s2[i]);
break;
}else{ //否则出栈
while (!sc2.empty())
{
temp2 = "";
temp2.append(1,sc2.top());
ans.push_back(temp2);
sc2.pop();
}
}
}
}
while (!sc2.empty()) //将栈中的操作符传入输出数组
{
temp2 = "";
temp2.append(1, sc2.top());
ans.push_back(temp2);
sc2.pop();
}
return ans;
}
int main(int argc, char const *argv[])
{
int t;
cin>>t;
while(t--){
string s;
cin>>s;
vector<string> ans1 = qianzhui(s);
for (auto it = ans1.rbegin(); it != ans1.rend(); it++) //输出
{
cout<<*it;
if(it != ans1.rend()-1){
cout<<" ";
}
}
cout<<endl;
vector<string> ans2 = houzhui(s);
for (auto it = ans2.begin(); it != ans2.end(); it++) //输出
{
cout<<*it;
if( it != ans2.end()-1){
cout<<" ";
}
}
if(t)cout<<endl<<endl;
}
return 0;
}