中缀表达式转换为后缀表达式及求值

 1、中缀(infix)表达式(expression)转换为后缀(postfix)表达式:(注:为了方便起见,表达式对象的输入输出均用空格分开)

  首先需要从头到尾读取中缀表达式中的每一个对象,建立一个堆栈

  (1)遇到操作数,直接输出;

  (2)遇到运算符,当该运算符大于栈顶运算符的优先级时,将该运算符压入栈中;如果该运算符的优先级小于或等于栈顶元素的优先级时,将栈顶元素弹出并输出,并比较新的

     栈顶运算符,知道该运算符大于栈顶运算符,并将该运算符压入栈中。

  (3)遇到左括号,将其压入栈中;

  (4)遇到右括号,将括号内的运算符依次弹出并输出,直到遇到左括号(左括号也出栈,但不输出)。

  (5)若中缀表达式中的对象处理完毕,则将栈中剩余的运算符弹出并输出。

代码如下:

  

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<stdbool.h>
  4 #include<ctype.h>
  5 #define MAXOP 100
  6 typedef struct SNode{
  7     char *Data;
  8     int Top;
  9     int Maxsize;
 10 }Stack;
 11 
 12 Stack *CreateStack(int Maxsize)
 13 {
 14     Stack *S;
 15     S=(Stack *)malloc(sizeof(struct SNode));
 16     S->Top=-1;
 17     S->Data=(char *)malloc(Maxsize * sizeof(char));
 18     S->Maxsize=Maxsize;
 19     return S;
 20 }
 21 
 22 bool IsFull(Stack *S)
 23 {
 24     return (S->Top==S->Maxsize-1);
 25 }
 26 
 27 void Push(Stack *S,char op)
 28 {
 29     if(!IsFull(S))
 30     {
 31         S->Data[++(S->Top)]=op;
 32     }
 33 }
 34 
 35 bool IsEmpty(Stack *S)
 36 {
 37     return (S->Top==-1);
 38 }
 39 
 40 char Pop(Stack *S)
 41 {
 42     char op;
 43     if (!IsEmpty(S))
 44     {
 45         op=S->Data[(S->Top)--];
 46     }
 47     return op;
 48 }                                     //以上是建立栈,及栈的基本操作
 49 
 50 /* 取出栈顶元素的函数 */
 51 char Top(Stack *S)
 52 {
 53     char op;
 54     if (!IsEmpty(S))
 55     {
 56         op=S->Data[(S->Top)];
 57     }
 58     return op;
 59 }
 60 
 61 typedef enum {num,opr,end}Type;
 62 
 63 /* 扫描中缀表达式中的每个对象,将其存在str数组中 。start传进去的是地址。str数组在每次函数调用的过程中其值会不断的变化*/
 64 Type GetOp(char *Expr,int *start,char *str)
 65 {
 66     int i=0;
 67     while ((str[0]=Expr[(*start)++])==' '); //跳过表达式对象前的空格
 68     while (str[i]!=' ' && str[i]!='\0') //遇到空格或结尾标识符,结束一个对象的获取
 69     {
 70         str[++i]=Expr[(*start)++];   //表达式存在str中
 71     }
 72     if (str[i]=='\0')(*start)--;  //start指向表达式末尾结束符'\0'
 73     str[i]='\0';    //结束一个对象的获取
 74 
 75     if (i==0) return end;
 76     else if (isdigit(str[0])||isdigit(str[1])) return num;  //考虑到类似于".3"这样的对象
 77     else return opr;
 78 }
 79 /* 优先级函数 */
 80 int Prior(char op)
 81 {
 82     switch (op)
 83     {
 84         case '*':
 85         case '/': return 2;
 86         case '+':
 87         case '-': return 1;
 88         case '(': return 0;  //当左括号压入栈中后,其优先级变得最低
 89     }
 90 }
 91 /*核心,中缀表达式转换为后缀表达式*/
 92 void PrintPostfixExp(char *Expr)
 93 {
 94     int start=0;
 95     Type T;
 96     char str[MAXOP];
 97     char op1,op2;
 98     Stack *S;
 99     S=CreateStack(MAXOP);
100     while((T=GetOp(Expr,&start,str))!=end)
101     {
102         if (T==num)printf("%s ",str);  //数字直接输出
103         else
104         {
105             switch(str[0])
106             {
107                 case '(':Push(S,str[0]);break; //左括号直接压入栈中
108                 case ')':
109                 {
110                     while(Top(S)!='(')printf("%c ",Pop(S)); //括号内的操作符弹出并输出
111                     Pop(S); //弹出左括号
112                     break;
113                 }
114                 case '+':
115                 case '-':
116                 case '*':
117                 case '/':
118                 {
119                     if (IsEmpty(S)){Push(S,str[0]);break;}  //栈是空的时候,直接压入栈中
120                     else
121                     {
122                         op1=Top(S);
123                         while (Prior(str[0])<=Prior(op1)) //依次将该对象和栈中的元素进行比较,直到栈不为空并且该操作符的优先级大于栈顶操作符优先级
124                          {printf("%c ",Pop(S));
125                             if (IsEmpty(S))op1=Top(S); //栈空时,退出循环
126                             else break;
127                         }
128                         Push(S,str[0]); //将该运算符压栈
129                     }
130                     break;
131                 }
132 
133             }
134         }
135     }
136     while(!IsEmpty(S))printf("%c ",Pop(S)); //将栈中剩余的运算符弹出并输出
137 }
138 
139 int main()
140 {
141     char Expr[MAXOP];
142     gets(Expr);
143     PrintPostfixExp(Expr);
144     return 0;
145 }
View Code

2、求值

  我是在“1”代码的基础上进行的改进,但强烈不建议这么做,因为我不知道怎么去处理出现了两个栈是冗杂重复的代码怎么解决

  (1)当对象是数时,压入栈中;

  (2)当对象是运算符时,从栈中弹出适当数量的运算符,进行运算并将结果压入栈中;

  (3)处理完整个后缀表达式后,栈顶元素就是结果。

代码如下:

  

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<stdbool.h>
  4 #include<ctype.h>
  5 #define MAXOP 100
  6 /* 以下一大段是两个堆栈的定义及其基本操作*/
  7 
  8 //目前我只会C语言,没有什么更好的办法去解决这一段的冗杂
  9 
 10 typedef struct SNode{       //第一个堆栈用来存放运算符
 11     char *Data;
 12     int Top;
 13     int Maxsize;
 14 }Stack;
 15 
 16 Stack *CreateStack(int Maxsize)
 17 {
 18     Stack *S;
 19     S=(Stack *)malloc(sizeof(struct SNode));
 20     S->Top=-1;
 21     S->Data=(char *)malloc(Maxsize * sizeof(char));
 22     S->Maxsize=Maxsize;
 23     return S;
 24 }
 25 
 26 bool IsFull(Stack *S)
 27 {
 28     return (S->Top==S->Maxsize-1);
 29 }
 30 
 31 void Push(Stack *S,char op)
 32 {
 33     if(!IsFull(S))
 34     {
 35         S->Data[++(S->Top)]=op;
 36     }
 37 }
 38 
 39 bool IsEmpty(Stack *S)
 40 {
 41     return (S->Top==-1);
 42 }
 43 
 44 char Pop(Stack *S)
 45 {
 46     char op;
 47     if (!IsEmpty(S))
 48     {
 49         op=S->Data[(S->Top)--];
 50     }
 51     return op;
 52 }
 53 char Top(Stack *S)
 54 {
 55     char op;
 56     if (!IsEmpty(S))
 57     {
 58         op=S->Data[(S->Top)];
 59     }
 60     return op;
 61 }
 62 
 63 typedef struct SNode1{      //第二个堆栈用来存放运算数
 64     float  *Data;
 65     int Top;
 66     int Maxsize;
 67 }Stack1;
 68 
 69 Stack1 *CreateStack1(int Maxsize)
 70 {
 71     Stack1 *S;
 72     S=(Stack1 *)malloc(sizeof(struct SNode));
 73     S->Top=-1;
 74     S->Data=(float *)malloc(Maxsize * sizeof(float));
 75     S->Maxsize=Maxsize;
 76     return S;
 77 }
 78 
 79 bool IsFull1(Stack1 *S)
 80 {
 81     return (S->Top==S->Maxsize-1);
 82 }
 83 
 84 void Push1(Stack1 *S,float op)
 85 {
 86     if(!IsFull1(S))
 87     {
 88         S->Data[++(S->Top)]=op;
 89     }
 90 }
 91 
 92 bool IsEmpty1(Stack1 *S)
 93 {
 94     return (S->Top==-1);
 95 }
 96 
 97 float Pop1(Stack1 *S)
 98 {
 99     float op;
100     if (!IsEmpty1(S))
101     {
102         op=S->Data[(S->Top)--];
103     }
104     return op;
105 }
106 
107 
108 typedef enum {num,opr,end}Type;
109 
110 Type GetOp(char *Expr,int *start,char *str)   //获取每个对象
111 {
112     int i=0;
113     while ((str[0]=Expr[(*start)++])==' ');
114     while (str[i]!=' ' && str[i]!='\0')
115     {
116         str[++i]=Expr[(*start)++];
117     }
118     if (str[i]=='\0')(*start)--;
119     str[i]='\0';
120 
121     if (i==0) return end;
122     else if (isdigit(str[0])||isdigit(str[1])) return num;
123     else return opr;
124 }
125 
126 int Prior(char op)
127 {
128     switch (op)
129     {
130         case '*':
131         case '/': return 2;
132         case '+':
133         case '-': return 1;
134         case '(': return 0;
135     }
136 }
137 /* 运算函数 */
138 void PushAns(Stack1 *S,char op)
139 {
140     float op1,op2;
141     if (!IsEmpty1(S))op1=Pop1(S);
142     if (!IsEmpty1(S))op2=Pop1(S);
143     switch (op)
144     {
145         case '+':Push1(S,op2+op1);break;
146         case '-':Push1(S,op2-op1);break;
147         case '*':Push1(S,op2*op1);break;
148         case '/':if (op2!=0.0)Push1(S,op2/op1);break;
149     }
150 }
151 
152 float PrintPostfixExp(char *Expr)
153 {
154     int start=0;
155     Type T;
156     char str[MAXOP];
157     char op1,op4;
158     float op2;
159     Stack *S;
160     Stack1 *S1;
161     S=CreateStack(MAXOP);
162     S1=CreateStack1(MAXOP);
163     while((T=GetOp(Expr,&start,str))!=end)
164     {
165         if (T==num)
166         {printf("%s ",str);
167          Push1(S1,atof(str));  //将数压入栈中
168         }
169         else
170         {
171             switch(str[0])
172             {
173                 case '(':Push(S,str[0]);break;
174                 case ')':
175                 {
176                     while(Top(S)!='(')
177                           {
178                               op4=Pop(S);
179                               printf("%c ",op4);
180                               PushAns(S1,op4);  //进行运算并将结果压入栈中
181                           }
182                     Pop(S);
183                     break;
184                 }
185                 case '+':
186                 case '-':
187                 case '*':
188                 case '/':
189                 {
190                     if (IsEmpty(S)){Push(S,str[0]);break;}
191                     else
192                     {
193                         op1=Top(S);
194                         while (Prior(str[0])<=Prior(op1))
195                         {
196                             op4=Pop(S);
197                             printf("%c ",op4);
198                             PushAns(S1,op4);  //进行计算并将结果压入栈中
199                             if (!IsEmpty(S))op1=Top(S);
200                             else break;
201                         }
202 
203                         Push(S,str[0]);
204                     }
205                     break;
206                 }
207 
208             }
209         }
210     }
211     while(!IsEmpty(S))
212     {
213         op4=Pop(S);
214         printf("%c ",op4);
215         PushAns(S1,op4);  //最后进行运算并将结果压入栈中
216     }
217     printf("\n");
218     printf("the ans is :");
219     if(!IsEmpty1(S1))op2=Pop1(S1);  //结果
220     free(S);
221     free(S1);
222     return op2;
223 }
224 
225 int main()
226 {
227     char Expr[MAXOP];
228     gets(Expr);
229     float op;
230     op=PrintPostfixExp(Expr);
231     printf("%.3f",op);
232     return 0;
233 }
View Code

 

转载于:https://www.cnblogs.com/wuxiaotianC/p/5802121.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值