**
7-5 表达式转换 (18 分)
**
算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
输入格式:
输入在一行中给出不含空格的中缀表达式,可包含+、-、*、\以及左右括号(),表达式不超过20个字符。
输出格式:
在一行中输出转换后的后缀表达式,要求不同对象(运算数、运算符号)之间以空格分隔,但结尾不得有多余空格。
输入样例:
2+3*(7-4)+8/4
//结尾无空行
输出样例:
2 3 7 4 - * + 8 4 / +
//结尾无空行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int ElementType;
typedef int QElemType;
typedef int Position;
typedef int Status;
typedef struct Node{//栈
ElementType *Data;
Position Top;
int MaxSize;
} SNode,*Stack;
Stack CreateStack(int MaxSize){//创建栈
Stack S = (Stack)malloc(sizeof(SNode));
S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
S->Top = -1;
S->MaxSize = MaxSize;
return S;
}
void Push( Stack S, ElementType x){//入栈
S->Top++;
S->Data[S->Top]=x;
}
ElementType Pop(Stack S){//出栈
int a;
if(S->Top!=-1){
a=S->Top;
S->Top--;
return S->Data[a];
}
else
return 0;
}
char GetTop(Stack S){//得倒栈顶的数据
return S->Data[S->Top];
}
int yxj(char x){//得到优先级
if(x=='#')
return -1;
else if(x=='('||x==')')
return 0;
else if(x=='+'||x=='-')
return 1;
else if(x=='*'||x=='/')
return 2;
else
return 0;
}
void zhuanta(Stack S,char a[]){
int i;
int flag=0;//判断第一个是否是负号(1为不是) 考虑表达式的第一个数是负数的情况
int flag1=0;//判断下一个是否为数字(1为不是) 考虑表达式的数是非一位的情况
int flag2=0;//判断是否是第一个(1为不是) 考虑在输出时空格的情况
int flag3=0;//判断‘(’的下一个是不是正负号(1为是) 考虑表达式的数字是负数的情况
char x;
Push(S,'#');
for(i = 0; i < strlen(a); i++){//循环
x=a[i];
if(isdigit(x)){//如果是数字或者有小数点
if(flag1==1&&flag2==1)//不是第一个且下一个是符号就打一个空格
printf(" ");
printf("%c",x);
flag=1;//第一个不是负号
flag1=0;//归零
flag2=1;//第一个不再可能是数字
flag3=0;//归零
}
else{//不是数字
flag1=1;//不是数字
if(((x=='+'||x=='-')&&flag==0)||((x=='+'||x=='-')&&flag3==1)){//如果是负数或者是带正号的数(考虑正负号)
if(x=='-')//如果是‘-’
printf("%c",x);//输出‘-’
flag3=0;//归零
}
else if(x=='+'||x=='-'||x=='*'||x=='/'){//如果是‘+’或‘-’或‘*’或‘/’
while(yxj(GetTop(S))>=yxj(x)){//栈内优先级大
printf(" %c", Pop(S));//输出
}
Push(S,x);//栈内优先级小就入栈
}
else if(x=='('){//如果是’(‘就入栈
Push(S,x);
flag3=1;//是左括号
}
else if(x==')'){//如果是’)‘
while(GetTop(S)!='('){//在没遇到‘(’之前出栈输出
printf(" %c",Pop(S));
flag2=1;//第一个不是数字
}
Pop(S);//删除‘(’
}
else if(x=='.'){//小数点
printf("%c",x);
flag1=0;//带小数的数字
}
}
}
while(S->Top!=0){//循环输出栈内的符号
printf(" %c", Pop(S));
}
}
int main(){
//存入数据
char a[105];
scanf("%s", a);
//建立栈
Stack S;
S=CreateStack(22);
zhuanta(S,a);
return 0;
}