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


     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]!='') //遇到空格或结尾标识符,结束一个对象的获取
     69     {
     70         str[++i]=Expr[(*start)++];   //表达式存在str中
     71     }
     72     if (str[i]=='')(*start)--;  //start指向表达式末尾结束符''
     73     str[i]='';    //结束一个对象的获取
     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]!='')
    115     {
    116         str[++i]=Expr[(*start)++];
    117     }
    118     if (str[i]=='')(*start)--;
    119     str[i]='';
    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("
    ");
    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
  • 相关阅读:
    Java+Selenium元素定位的练习(三)
    Java+Selenium元素定位的八种方法(二)
    Java Selenium3 WebDriver启动火狐、Chrome、IE,Edge浏览器的方法(一)
    iOS userAgent
    如何强制视频横竖屏
    一些在开发中不曾注意的小知识,只是怕以后忘了,有迹可查
    多线程与并发
    谈谈那些年要把你弄疯的 bug
    底部导航上拉出现,下拉消失
    新闻详情页顶部的下拉放大与上拉的层叠效果
  • 原文地址:https://www.cnblogs.com/wuxiaotianC/p/5802121.html
Copyright © 2020-2023  润新知