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


    中缀表达式即普通的运算式子,运算符是以中缀形式处于操作数的中间(例: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("请按中缀表达式输入式子,以'#'作为结束符:
    ");
     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("
     出错");
    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()这样的语句太多,还有"{}"也很多,格式整齐了就不易出错并且便于调试发现错误。

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

  • 相关阅读:
    Java中会存在内存泄漏吗,请简单描述。
    什么是类加载器
    通俗易懂 索引、单列索引、复合索引、主键、唯一索引、聚簇索引、非聚簇索引、唯一聚簇索引 的区别与联系
    Redis真的那么好用吗
    java中public,private,protected和default的区别
    聚集和非聚集索引
    我以为我对Mysql索引很了解,直到我遇到了阿里的面试官(转)
    Java中存储金额用什么数据类型
    InnoDB在MySQL默认隔离级别下解决幻读
    android应用程序第一次启动时显示引导界面
  • 原文地址:https://www.cnblogs.com/caiyineng/p/4902654.html
Copyright © 2020-2023  润新知