
#include <stdio.h>
#include <stdlib.h>
#include<stdbool.h>
#include<string.h>
#include<ctype.h>
#define Max 21
typedef struct Node{
char data[Max];
int top;
}NODE,*pNODE;
typedef enum{
a,b,c,d,e,f,g,h
}Pre;
Pre Get(char op){
switch(op){
case '(':return a;
case ')':return b;
case '+':return c;
case '-':return d;
case '*':return e;
case '/':return f;
case '\0':return g;
default:return h;
}
}
//初始化
void init(pNODE pS){
pS->top=-1;
}
//入栈
bool add(pNODE pS,int val){
if(pS->top==Max-1){
return false;
}
pS->top++;
pS->data[pS->top]=val;
return true;
}
//出栈
bool delete(pNODE pS, char *pVal){
if(pS->top==-1){
return false;
}
*pVal=pS->data[pS->top];
pS->top--;
return true;
}
//访问栈顶元素
char peek(pNODE pS){
char Val;
Val=pS->data[pS->top];
return Val;
}
//判断是否为空
bool empty(pNODE pS){
if(pS->top==-1)
return true;
else
return false;
}
//判断是正负号还是运算符
bool IsSign(char* str,int i){
//如果前一个字符不是数字也不是右括号,则是正负号
//表达式第一个字符 正负号
if(!i||(!isdigit(str[i-1])&&(str[i-1]!=')'))){
return true;
}
else return false;//是运算符
}
char GetOp(char* str,int *i,char *str1,int *j){
if(isdigit(str[(*i)])){
//执行循环前说明此时字符已经是数字,进入循环,如果下一个字符是数字,说明是一个十位数,则不加空格,是小数点说明这个数是小数,中间不加空格
while(isdigit(str[(*i)])||(str[(*i)])=='.'){
str1[(*j)++]=str[(*i)++];
}
str1[(*j)++]=' ';
//再表达式转换函数中,遇到数字不执行,直接跳出循环,所以i要减一,否则在表达式转换函数中又再for循环中加了一次,这样就会加了两次
(*i)--;
// printf("%d\n",(*i));
return '0';
}
switch(str[(*i)]){
case '+':
if(IsSign(str,(*i))){
(*i)++;
return GetOp(str,i,str1,j);}
else return '+';
case '-':
if(IsSign(str,(*i))){
str1[(*j)++]='-';
(*i)++;
return GetOp(str,i,str1,j);}
else return '-';
default:
return str[(*i)];
}
}
void convert(char* str){
char str1[Max*2];
int j=0;
char val;
char token;
int len=strlen(str);
pNODE S=(pNODE)malloc(sizeof(NODE));
if(S == NULL) return false; //分配失败
init(S);
for(int i=0;i<len;i++){
token=GetOp(str,&i,str1,&j);
Pre op=Get(token);
if(op==h)continue;
switch(op){
case a:add(S,'(');
break;
case b:while(peek(S)!='('){
delete(S,&val);
str1[j++]=val;
str1[j++]=' ';
}
delete(S,&val);
break;
default:
//当前运算符优先级小于等于栈顶运算符优先级,直接出栈并输出
while(!empty(S)&&peek(S)!='('&&op<=Get(peek(S))){
delete(S,&val);
str1[j++]=val;
str1[j++]=' ';
}
add(S,str[i]);//当前运算符大于栈顶运算符,压栈
break;
}
}
//中缀表达式对象处理完毕栈中剩余元素输出
while(!empty(S)){
delete(S,&val);
str1[j++]=val;
str1[j++]=' ';
}
str1[j-1]='\0';
printf("%s",str1);
}
int main()
{
char str[Max]={0};
gets(str);
int len=strlen(str);
convert(str);
return 0;
}
