数据结构-栈应用之逆波兰表达式(后缀表达式)

迈不过友情╰ 2022-05-12 13:20 294阅读 0赞

逆波兰表达式含义我就不做赘述了,摘自百科上的一段话:

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。
逆波兰表达式,它的语法规定,表达式必须以逆波兰表达式的方式给出。逆波兰表达式又叫做后缀表达式。这个知识点在数据结构和编译原理这两门课程中都有介绍,下面是一些例子:
正常的表达式 逆波兰表达式
a+b —-> a,b,+
a+(b-c) —-> a,b,c,-,+
a+(b-c)*d —-> a,b,c,-,d,*,+
a+d*(b-c)—->a,d,b,c,-,*,+
a=1+3 —-> a,1,3,+,=

用途

逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)*(c+d)转换为ab+cd+*

优势

它的优势在于只用两种简单操作,入栈和出栈就可以搞定任何普通表达式的运算。其运算方式如下:
如果当前字符为变量或者为数字,则压栈,如果是运算符,则将栈顶两个元素弹出作相应运算,结果再入栈,最后当表达式扫描完后,栈里的就是结果。

以上红线为划重点,如果没理解这句话的意思,那么接下来的代码就不用看了(无奈~~)

  1. //
  2. // Created by Administrator on 2018/5/28.
  3. //
  4. //逆波兰表达式(后缀表达式)
  5. #include "stdio.h"
  6. #include "stdlib.h"
  7. #include "string.h"
  8. #define ElementType int
  9. #define MaxSize 20
  10. //定义栈的结构体
  11. typedef struct {
  12. ElementType *top;//栈顶指针(这里定义为指向栈顶元素的下一个位置,即为空)
  13. ElementType *base;//栈底指针
  14. int stackSize;//栈的容量
  15. } Stack;
  16. /**
  17. * 初始化栈
  18. * @param s
  19. */
  20. void InitStack(Stack *s) {
  21. //初始化分配栈的总空间
  22. s->base = (ElementType *) malloc(MaxSize * sizeof(ElementType));
  23. if (!s->base) {
  24. //分配失败
  25. printf("初始化分配空间失败!");
  26. exit(0);
  27. }
  28. s->top = s->base;
  29. s->stackSize = MaxSize;
  30. }
  31. /**
  32. * 入栈
  33. * @param s 栈
  34. * @param e 入栈元素
  35. */
  36. void Push(Stack *s, ElementType e) {
  37. //判断栈是否已满
  38. if (s->top - s->base >= s->stackSize) {
  39. //栈已满
  40. //处理方式1.递增空间 2.退出
  41. printf("栈已满~\n");
  42. exit(0);
  43. }
  44. *(s->top) = e; //赋值
  45. s->top++;
  46. }
  47. /**
  48. * 出栈
  49. * @param s 栈
  50. * @return
  51. */
  52. ElementType Pop(Stack *s) {
  53. //判断栈是否为空
  54. if (s->base == s->top) {
  55. //栈为空
  56. //printf("\n不好意思,栈目前为空~\n");
  57. return -1;
  58. }
  59. s->top--;
  60. ElementType e = *(s->top);//取值,并不是取地址
  61. return e;
  62. }
  63. /**
  64. * 栈当前容量
  65. * @param s
  66. * @return
  67. */
  68. ElementType GetLen(Stack s) {
  69. int len = (s.top - s.base);
  70. return len;
  71. }
  72. int main() {
  73. //存在中缀表达式:1+2*(4-3)+6/6
  74. //转换为后缀表达式:1234-*+66/+
  75. char exp[] = {'1', '2', '4', '3', '-', '*', '+', '6', '6', '/', '+'};
  76. Stack stack;
  77. InitStack(&stack);
  78. int len = strlen(exp);
  79. int length = sizeof(exp) / sizeof(exp[0]);
  80. for (int i = 0; i < length; i++) {
  81. char p = exp[i];
  82. int temp;
  83. ElementType a;
  84. ElementType b;
  85. switch (p) {
  86. case '+':
  87. a = Pop(&stack);
  88. b = Pop(&stack);
  89. temp = b + a;
  90. Push(&stack, temp);
  91. break;
  92. case '-':
  93. a = Pop(&stack);
  94. b = Pop(&stack);
  95. temp = b - a;
  96. Push(&stack, temp);
  97. break;
  98. case '*':
  99. a = Pop(&stack);
  100. b = Pop(&stack);
  101. temp = b * a;
  102. Push(&stack, temp);
  103. break;
  104. case '/':
  105. a = Pop(&stack);
  106. b = Pop(&stack);
  107. if (b == 0) {
  108. printf("除数不能为0~\n");
  109. return -1;
  110. }
  111. temp = b / a;
  112. Push(&stack, temp);
  113. break;
  114. default:
  115. temp = p - 48;
  116. Push(&stack, temp);
  117. break;
  118. }
  119. }
  120. char sum = Pop(&stack);
  121. printf("\n表达式计算结果 value=%d\n", sum);
  122. }

70

发表评论

表情:
评论列表 (有 0 条评论,294人围观)

还没有评论,来说两句吧...

相关阅读