习题3.11 表达式转换(25 分)
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
输出样例:
2 3 7 4 - * + 8 4 / +
思路:
/*
a. 若为 '(',入栈;
b. 若为 ')',则依次把栈中的的运算符加入后缀表达式中,直到出现'(',从栈中删除'(' ;
c. 若为 除括号外的其他运算符, 当其优先级高于除'('以外的栈顶运算符时,直接入栈。
否则从栈顶开始,依次弹出比当前处理的运算符优先级高和优先级相等的运算符,
直到一个比它优先级低的或者遇到了一个左括号为止。
·当扫描的中缀表达式结束时,栈中的的所有运算符出栈;
*/
#include<stdio.h>
#include<string.h>
int IsNum(char ch);
int Zhengfu(char ch);
int compare(char a,char b);
void F(char *a,int len);
int main(){
char a[25];
scanf("%s",a);
int len=strlen(a);
F(a,len);
return 0;
}
int IsNum(char ch){
return ch>='0'&&ch<='9'||ch=='.';
}
int Zhengfu(char ch){
return ch=='+'||ch=='-';
}
int compare(char a,char b){ //判断是否出栈
if(b==')') return 1;
if(a=='('||b=='(') return 0;
if(b=='+'||b=='-') return 1;
else if(b=='*'||b=='/'){
if(a=='+'||a=='-') return 0;
else if(a=='*'||a=='/') return 1;
}
}
void F(char *a,int len){
char stack[25];
int top=0;
int space = 0;
for(int i=0;i<len;i++){
if(IsNum(a[i])){
if(space){
printf(" ");
space = 0;
}
printf("%c",a[i]);
}
else if(Zhengfu(a[i])&&(i?!IsNum(a[i-1])&&a[i-1]!=')':1)){//如果不是运算符,则直接输出
if(a[i]=='-'){ //只输出负号
if(space){
printf(" ");
space=0;
}
printf("%c",a[i]);
}
}
else{
if(top){
if(a[i]==')')
while(top--){
if(stack[top]=='(') break;
printf(" %c",stack[top]);
}
else{
while(top){
if(compare(stack[top-1],a[i])){
printf(" %c",stack[--top]);
}
else break;
}
stack[top++]=a[i];
}
}
else stack[top++]=a[i];
for(int j=0;j<top;j++)
if(stack[j]!='('){
space = 1;
break;
}
}
}
while(top){
printf(" %c",stack[--top]);
}
}