码迷,mamicode.com
首页 > 其他好文 > 详细

从中序表达式到逆序表达式(逆波兰式)(四则运算表达式求值)

时间:2015-07-07 12:43:02      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:

本份代码需要两个栈。一个是符号栈,一个是数字栈。

输入中序表达式如9+(3-1)*3+10/2#
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<math.h>
  4. #define max 100
  5. char ex[max]; /*存储后序表达式*/
  6. /*函数功能:将中序表达式转化为后序表达式*/
  7. void trans() {
  8. char str[max]; /*表达式字符串*/
  9. char stack[max]; /*运算符栈*/
  10. char ch; /*当前字符*/
  11. int sum, i, j, t, top = 0; /*sum用来统计字符串的长度*/
  12. /*t是数字栈栈顶指针*/
  13. /*top是数字栈栈顶指针*/
  14. printf("*****************************************\n");
  15. printf("*输入一个求值的表达式,以#结束。*\n");
  16. printf("******************************************\n");
  17. printf("算数表达式:");
  18. i = 0;
  19. /*这个循环语句,获取一个用户输入的合法的表达式*/
  20. do {
  21. i++;
  22. scanf("%c", &str[i]);
  23. } while (str[i] != ‘#‘ && i != max);
  24. sum = i;
  25. t = 1;
  26. i = 1;
  27. ch = str[i];
  28. i++;
  29. //while循环,当前的字符不是#
  30. while (ch != ‘#‘) {
  31. //将该字符与运算符栈顶的运算符的优先关系相比较。
  32. //如果该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。
  33. //括号的运算优先级高。
  34. switch (ch) {
  35. case ‘(‘: /*判定为左括号,入符号栈*/
  36. top++; /*栈顶指针+1*/
  37. stack[top] = ch;
  38. break;
  39. case ‘)‘: /*判定为右括号*/
  40. while (stack[top] != ‘(‘) {
  41. ex[t] = stack[top];/*把符号栈的栈顶元素压入另一个栈中*/
  42. top--; /*符号栈的栈顶指针-1*/
  43. t++; /*数字栈的栈顶指针+1*/
  44. }
  45. top--;
  46. break;
  47. case ‘+‘: /*判定为加减号*/
  48. case ‘-‘:
  49. while (top != 0 && stack[top] != ‘(‘) {
  50. ex[t] = stack[top];/*把符号栈的栈顶元素压入数字栈中*/
  51. top--; /*符号栈的栈顶指针-1*/
  52. t++; /*数字栈的栈顶指针+1*/
  53. }
  54. top++;
  55. stack[top] = ch; /*不执行那个while循环的话,直接压入符号栈*/
  56. break;
  57. case ‘*‘: /*判定为乘除号*/
  58. case ‘/‘:
  59. while (stack[top] == ‘*‘ || stack[top] == ‘/‘) {
  60. ex[t] = stack[top];/*把符号栈的栈顶元素压入数字栈中*/
  61. top--; /*符号栈的栈顶指针-1*/
  62. t++; /*数字栈的栈顶指针+1*/
  63. }
  64. top++;
  65. stack[top] = ch;
  66. break;
  67. case ‘ ‘:/*滤去空格*/
  68. break;
  69. default:/*默认直接把数字压入数字栈*/
  70. while (ch >= ‘0‘ && ch <= ‘9‘) { /*判定为数字*/
  71. ex[t] = ch; /*把数字压入数字栈*/
  72. t++; /*数字栈栈顶指针+1*/
  73. /*这边的代码写得很巧妙*/
  74. ch = str[i]; /*从字符串中取一个字符*/
  75. i++; /*字符数组下标+1*/
  76. }
  77. i--;
  78. ex[t] = ‘#‘; /*为每个数字加一个分隔符*/
  79. t++;
  80. }
  81. ch = str[i];
  82. i++;
  83. }
  84. /*把符号栈剩下的元素压进去*/
  85. while (top != 0) {
  86. ex[t] = stack[top];
  87. t++;
  88. top--;
  89. }
  90. ex[t] = ‘#‘;
  91. printf("\n原来的中序表达式:");
  92. for (j = 1; j < sum; j++)
  93. printf("%c", str[j]);
  94. printf("\n后缀表达式:");
  95. for (j = 1; j < t; j++)
  96. printf("%c", ex[j]);
  97. }
  98. void compvalue() { /*计算后缀表达式的值*/
  99. float stack[max], d; /*作为栈使用*/
  100. char ch;
  101. int t = 1, top = 0; /*t为ex下标,top为stack下标*/
  102. ch = ex[t];
  103. t++;
  104. //从左到右检查字符串
  105. while (ch != ‘#‘) {/*滤去#*/
  106. switch (ch) {
  107. //发现运算符,用栈顶的两个元素进行运算。
  108. case ‘+‘:
  109. stack[top - 1] = stack[top - 1] + stack[top];
  110. top--;
  111. break;
  112. case ‘-‘:
  113. stack[top - 1] = stack[top - 1] - stack[top];
  114. top--;
  115. break;
  116. case ‘*‘:
  117. stack[top - 1] = stack[top - 1] * stack[top];
  118. top--;
  119. break;
  120. case ‘/‘:
  121. if (stack[top] != 0)
  122. stack[top - 1] = stack[top - 1] / stack[top];
  123. else {
  124. printf("\n\t除零错误!\n");
  125. //exit(0); /*异常退出*/
  126. }
  127. top--;
  128. break;
  129. default:
  130. d = 0;
  131. while (ch >= ‘0‘ && ch <= ‘9‘) {
  132. d = 10 * d + ch - ‘0‘; /*将数字字符转化为对应的数值*/
  133. ch = ex[t];
  134. t++;
  135. }
  136. top++;
  137. stack[top] = d;
  138. }
  139. ch = ex[t];
  140. t++;
  141. }
  142. printf("\n\t计算结果:%g\n", stack[top]);
  143. }
  144. int main() {
  145. trans(); //转化成逆波兰式
  146. compvalue(); //计算值
  147. return 0;
  148. }

技术分享

计算过程
技术分享




 

从中序表达式到逆序表达式(逆波兰式)(四则运算表达式求值)

标签:

原文地址:http://www.cnblogs.com/zhuzhenfeng/p/4626564.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!