中缀表达式转换成后缀表达式

中缀表达式即普通的运算式子,运算符是以中缀形式处于操作数的中间(例:3 + 4),后缀表达式就是逆波兰式(例:3 4 +),中缀表达式转后缀表达式也是学习数据结构中的栈的时候一个典型的例子,结合上一次写到逆波兰式。可以用这种原理即输入普通式子(即中缀表达式),转换成后缀表达式,然后通过后缀表达式(逆波兰式)的计算,可以得出结果。

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define STACK_INIT_SIZE 20
  4 #define STACK_INCREMENT 10
  5 typedef char ElemType;
  6 typedef char Status;
  7 
  8 typedef struct
  9 {
 10     ElemType *base;
 11     ElemType *top;
 12     int stacksize;
 13 }SqStack;
 14 
 15 Status InitStack( SqStack *S )
 16 {
 17     S->base = ( ElemType *) malloc (  STACK_INIT_SIZE*sizeof( ElemType ) );
 18     S->top  = S->base ;
 19     S->stacksize = STACK_INIT_SIZE;
 20 
 21     return 0;
 22 }
 23 
 24 //插入元素e,即入栈
 25 Status Push( SqStack *S , ElemType e )
 26 {
 27     if ( S->top - S->base >= S->stacksize )  //当前容量大于或等于最大容量
 28     {
 29     //追加栈的空间
 30     S->base = ( ElemType *) realloc ( S->base,  S->stacksize + STACK_INCREMENT*sizeof( ElemType ) );
 31     if ( !S->base )
 32         return  -1;
 33     S->top = S->base  + S->stacksize ;
 34     S->stacksize = S->stacksize + STACK_INCREMENT;
 35 
 36     }
 37     //开始赋值
 38     *S->top = e;
 39     S->top++;
 40 
 41     return 0;                              //注意返回值为0,不是e
 42 }
 43 
 44 //弹出元素e,即出栈
 45 Status Pop ( SqStack *S , ElemType *e )//此处S为结构体指针的变量,所以访问结构体成员用"->"
 46 {
 47     //首先判断栈内是否为空
 48     if ( S->top == S->base )
 49     return -1 ;
 50 
 51     --S->top ;
 52     *e = *S->top ;
 53 
 54     return *e;                         //注意返回值为e,不是0
 55 }
 56 
 57 int StackLen ( SqStack S )//S为结构体变量,所以访问结构体成员用"."
 58 {
 59     return  ( S.top - S.base );
 60 }
 61 
 62 int main()
 63 {
 64    SqStack s;
 65    char c,e;
 66    InitStack(&s);
 67    printf("请按中缀表达式输入式子,以'#'作为结束符:\n");
 68    scanf("%c",&c);
 69    while(c!='#')
 70    {
 71        while(c>='0'&&c<='9')
 72        {
 73            printf("%c",c);
 74            scanf("%c",&c);
 75            if(c<'0'||c>'9')
 76            {
 77                printf(" ");
 78            }
 79        }
 80            if(')'==c)
 81            {
 82                 Pop(&s,&e);
 83                 while('('!=e)
 84                 {
 85                     printf("%c ",e);
 86                     Pop(&s,&e);
 87                 }
 88            }
 89            else if('+'==c||'-'==c)
 90            {
 91                if(!StackLen(s))
 92                {
 93                    Push(&s,c);
 94                }
 95                else
 96                {
 97                    do
 98                    {
 99                        Pop(&s,&e);
100                        if('('==e)
101                        {
102                            Push(&s,e);
103                        }
104                        else
105                        {
106                            printf("%c ",e);
107                        }
108                    }while(StackLen(s)&&'('!=e);
109                    Push(&s,c);
110                }
111            }
112 
113            else if('*'==c||'/'==c||'('==c)
114            {
115                 Push(&s,c);
116            }
117            else if('#'==c)
118            {
119                break;
120            }
121            else
122            {
123                printf("\n 出错");
124                return -1;
125            }
126            scanf("%c",&c);
127    }
128        while(StackLen(s))
129        {
130            Pop(&s,&e);
131            printf("%c ",e);
132        }
133    return 0;
134 }

上面程序中几个注意点:一是出现iif(')'==c)的表达式,将')'写在了'=='的左边,这有助于调试发现错误,防止有些程序员将'=='打成'=';不然的话即使打成c=')'编译器也不会发现错误,认为是赋值,而')'=c这样的式子式错误的,因为无法将变量赋值给常数;二是入栈函数(Push)和出栈函数(Pop)作为子函数式写有关栈的程序的必备子程序,可以将他们制作成头文件,以后可以直接调用。三是编程的格式,因为while().if(),

else if()这样的语句太多,还有"{}"也很多,格式整齐了就不易出错并且便于调试发现错误。

运算结果中有空格,这也是需要在程序中改进的。

 

转载于:https://www.cnblogs.com/caiyineng/p/4902654.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值