《数据结构和算法》之中缀表达式、后缀表达式转换

转载博客:https://blog.csdn.net/huangchijun11/article/details/60963444

一,在上篇博文中讨论了逆波兰表达式的计算问题,在这里讨论一下中缀表达式如何转换为后缀表达式

       问题示例:如何将1+(2-3)*4+10/5 转换为后缀表达式 1 2 3 - 4 * + 10 5 / +这样的输出

       问题分析:

       第一步,首先遇到第一个输入是数字1,数字在后缀表达式中都是直接输出,接着是符号“+”入栈

                                               

       第二步,第三个字符是“(”,依然是符号,这个时候将此符号入栈,接着是数字2,直接输出,然后是符号“-”,这个时候符号仍然入栈

                                                  

     第三步,接下来是数字3,输出,紧跟着是“)”,此时,我们需要匹配栈里的“(”,然后再匹配前将栈顶数据依次出栈:

                                            

     第四步,紧接着是符号“*”,直接入栈:

                                             

      第五步,遇到数字4,直接输出,之后是符号“+”,此时栈顶元素是符号“*”,按照先乘除后加减原理,此时栈顶的乘号优先级比即将入栈的加号要大,所以出栈。而栈中的第二个元素是加号,按照先到先后的原则,这个时候“+”也要出栈。

                                            

       第六步,紧接着是数字10,直接输出,最后是符号“/”,进栈:

                                           

      第七步,最后一个数字5,这个时候直接输出5,但是栈里仍然有数据,此时可以将栈中符号依次出栈。

二,代码分析:

                 

 
  1. #include <stdio.h>

  2. #include <stdlib.h>

  3. #include <ctype.h>

  4.  
  5. #define STACK_INIT_SIZE 20

  6. #define STACKINCREMENT 10

  7. #define MAXBUFFER 10

  8.  
  9. typedef char ElemType;

  10. typedef struct

  11. {

  12. ElemType *base;

  13. ElemType *top;

  14. int stackSize;

  15. }sqStack;

  16.  
  17. void InitStack(sqStack *s)

  18. {

  19. s->base = (ElemType *)malloc(STACK_INIT_SIZE * sizeof(ElemType));

  20. if( !s->base )

  21. exit(0);

  22.  
  23. s->top = s->base;

  24. s->stackSize = STACK_INIT_SIZE;

  25.  
  26. }

  27.  
  28. void Push(sqStack *s, ElemType e)

  29. {

  30. //如果栈满一定要增加空间,所以在之前要做一个判断

  31. if( s->top - s->base >= s->stackSize)

  32. {

  33. s->base = (ElemType *)realloc(s->base, (s->stackSize + STACKINCREMENT)* sizeof(ElemType));

  34. if(!s->base)

  35. exit(0);

  36.  
  37. s->top = s->base + s->stackSize;

  38. s->stackSize = s->stackSize + STACKINCREMENT;

  39. }

  40.  
  41. *(s->top) = e;

  42. s->top++;

  43.  
  44. }

  45.  
  46. void Pop(sqStack *s, ElemType *e)

  47. {

  48. if( s->top == s->base)

  49. return;

  50.  
  51. *e = *--(s->top); //将栈顶元素弹出并修改栈顶指针

  52.  
  53. }

  54.  
  55. int StackLen(sqStack s)

  56. {

  57. return (s.top - s.base);

  58. }

  59.  
  60. int main()

  61. {

  62. sqStack s;

  63. ElemType c,e;

  64.  
  65.  
  66. InitStack( &s );

  67.  
  68. printf("请输入中缀表达式,以#为结束标志:");

  69. scanf("%c", &c);

  70.  
  71. while( c != '#')

  72. {

  73. if( c >= '0' && c <= '9')

  74. {

  75. printf("%c", c);

  76. }

  77. else if( ')' == c )

  78. {

  79. Pop(&s, &e);

  80. while('(' != e)

  81. {

  82. printf("%c", e);

  83. Pop(&s, &e);

  84. }

  85. }

  86. else if( '+' == c || '-' == c)

  87. {

  88. if( !StackLen(s) )

  89. {

  90. Push(&s, c);

  91. }

  92. else

  93. {

  94. do

  95. {

  96. Pop(&s, &e);

  97. if( '(' == e)

  98. {

  99. Push(&s, e);

  100. }

  101. else

  102. {

  103. printf("%c", e);

  104. }

  105. }while( StackLen(s) && '(' != e);

  106. Push(&s, c);

  107. }

  108. }

  109. else if( '*' == c || '/' == c || '(' == c)

  110. {

  111. Push(&s, c);

  112. }

  113. else

  114. {

  115. printf("输入错误,请重新输入!\n");

  116. return -1;

  117. }

  118. scanf("%c", &c);

  119. }

  120.  
  121. while( StackLen(s))

  122. {

  123. Pop( &s, &e);

  124. printf("%c", e);

  125. }

  126. return 0;

  127. }

  128.  

              最后的结果

                                   

           大家可以看到这样的结果直接连在一起了,很难分辨出来是123还是1 2 3,这个时候就要在输出做一个改动,将printf("%c"改为printf("%c ",加了一个空格,但是出现了这样的结果:

                                      

              这样可以看到10被拆分成了1 0,显然这样是不合理的。此时再修改程序,将主函数main修改如下:

                        

 
  1. int main()

  2. {

  3. sqStack s;

  4. ElemType c,e;

  5.  
  6.  
  7. InitStack( &s );

  8.  
  9. printf("请输入中缀表达式,以#为结束标志:");

  10. scanf("%c", &c);

  11.  
  12. while( c != '#')

  13. {

  14. while( c >= '0' && c <= '9')

  15. {

  16. printf("%c", c);

  17. scanf("%c",&c);

  18. if( c<'0' || c>'9')

  19. {

  20. printf(" ");

  21. }

  22. }

  23.  
  24. if( ')' == c )

  25. {

  26. Pop(&s, &e);

  27. while('(' != e)

  28. {

  29. printf("%c ", e);

  30. Pop(&s, &e);

  31. }

  32. }

  33. else if( '+' == c || '-' == c)

  34. {

  35. if( !StackLen(s) )

  36. {

  37. Push(&s, c);

  38. }

  39. else

  40. {

  41. do

  42. {

  43. Pop(&s, &e);

  44. if( '(' == e)

  45. {

  46. Push(&s, e);

  47. }

  48. else

  49. {

  50. printf("%c ", e);

  51. }

  52. }while( StackLen(s) && '(' != e);

  53. Push(&s, c);

  54. }

  55. }

  56. else if( '*' == c || '/' == c || '(' == c)

  57. {

  58. Push(&s, c);

  59. }

  60. else if( '#' == c)

  61. {

  62. break;

  63. }

  64. else

  65. {

  66. printf("输入错误,请重新输入!\n");

  67. return -1;

  68. }

  69. scanf("%c", &c);

  70. }

  71.  
  72. while( StackLen(s))

  73. {

  74. Pop( &s, &e);

  75. printf("%c ", e);

  76. }

  77. return 0;

  78. }

             最终得出想要的满意结果:

                                   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值