7-20 表达式转换 (25分)
前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前。
中缀表达式就是常见的运算表达式。这个东西从小到大一直在使用,因为人们很容易接受。
后缀表达式又叫做逆波兰表达式。逆波兰表示法是波兰逻辑学家J・卢卡西维兹(J・ Lukasewicz)于1929年首先提出的一种表达式的表示方法。后来,人们就把用这种表示法写出的表达式称作“逆波兰表达式”。逆波兰表达式把运算量写在前面,把算符写在后面。
这篇文章写的非常好,太喜欢这种博客的写作方式了,以后我也要多加一些干货。逆波兰表达式求值
例如:
对于表达式 Exp = a * b + (c - d / e) * f
前缀表达式为: + * a b * - c / d e f
中缀表达式为: a * b + c - d / e * f
后缀表达式为: a b * c d e / - f * +
这个题,我tm写了好久啊!
好多天没有思路,我直接要崩溃了啊。
3-7 表达式转换 (20分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\ 以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
AC【借鉴】
这里涉及到各种符号的优先级,好好记住!!!
#include<bits/stdc++.h>
using namespace std;
int main(){
/*ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);*/
//加快C++输入输出的,这里不写也可以。
string s;
cin>>s;
int len=0;
//这里先查看第一个数字的长度,包括判断是不是小数
for(int i=0;i<s.length();i++){
if(s[i]>='0'&&s[i]<='9'||s[i]=='.')
len++;
}
//如果只有一个数字的话,输出这个数字。程序结束。
if(len==s.length()){
cout<<s;
return 0;
}
//判断第一个数字前有没有负号
if(s[0]=='-'){
s=s.substr(1);//取字符串下标从1直到结束的字符串
cout<<"-";
}
stack<char> st;
string res;
for(int i=0;i<s.length();i++){
if(s[i]>='0'&&s[i]<='9'){
int j=i+1;
while(s[j]>='0'&&s[j]<='9'||s[j]=='.')
j++;//如果下一字符也是数字,接着遍历,运算数可能是多位数
res=res+s.substr(i,j-i)+" ";
i=j-1;//一次循环之后,i要加1,所以这里减去1
}else{
char op=s[i];
if(op=='+'&&s[i-1]!='('||op=='-'&&s[i-1]!='('){
//后面是加减号,不入栈
while(!st.empty()&&st.top()!='('){
res=res+st.top()+" ";
st.pop();
}
st.push(op);//低优先级的运算符最后入栈
}else if(op=='*'||op=='/'||op=='('){
st.push(op);//高优先级的直接入栈
}else if(op==')'){
//遇到右括号,出栈,知道遇到左括号
while(st.top()!='('){
res=res+st.top()+" ";
st.pop();
}
st.pop();//弹出左括号,不输出。
}
}
}
while(!st.empty()){//把栈内的元素全部弹出
res=res+st.top();
if(st.size()>1) res=res+" ";
st.pop();
}
cout<<res;
return 0;
}