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


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

    输入中序表达式如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("***************************************** ");
    15. printf("*输入一个求值的表达式,以#结束。* ");
    16. printf("****************************************** ");
    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(" 原来的中序表达式:");
    92. for (j = 1; j < sum; j++)
    93. printf("%c", str[j]);
    94. printf(" 后缀表达式:");
    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(" 除零错误! ");
    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(" 计算结果:%g ", stack[top]);
    143. }
    144. int main() {
    145. trans(); //转化成逆波兰式
    146. compvalue(); //计算值
    147. return 0;
    148. }

    20131202195444703.jpg

    计算过程
    20140101130903187.jpg




  • 相关阅读:
    TransactionScope和Enterprise Libray 3.0 Data Access Application Block
    C#之父 Anders Hejlsberg
    openSUSE Linux 10.2 多语言版
    承蒙各位朋友支持与厚爱,荣获asp.net MVP荣誉
    如何在ASP.NET 2.0中定制Expression Builders
    检查Python对象
    IronPython中使用Cecil类库指南
    MSDN Magazine 4月份asp.net文章
    Reflector 插件
    WSS v3的Form身份认证
  • 原文地址:https://www.cnblogs.com/zhuzhenfeng/p/4626564.html
Copyright © 2020-2023  润新知