利用栈对中缀表达式求值

需要创建两个栈,一个用来存操作数,另一个用来存操作符;
算法思想:
(1)依次扫描中缀表达式
(2)遇到操作数直接入栈
(3)遇到操作符,有以下几种情况
  a:栈空直接入栈
  b:遇到’(‘直接入栈
  c:遇到 ’)‘ 则出栈并弹出操作数栈中栈顶的两个元素做相应的运算,直到遇到 ’(' 为止。(栈顶两个元素运算时要注意次序,第一个出栈的在后,第二个在前。
  d:遇到运算符优先级高于栈顶运算符优先级,则入栈
  e:遇到运算符优先级低于或等于栈顶运算符优先级,则出栈,直到其优先级高于栈顶运算符优先级时停止(或栈为空),最后再将其入栈
  f:直到中缀表达式扫描结束
(4)中缀表达式扫描结束后,如果运算符栈中还有运算符,一直出栈并与运算值栈做相应操作(与步骤(3)中c的操作相同),直到栈空
(5)此时运算值栈中剩一个元素,即为最终结果

完整代码:

#include <stdio.h>
  8 #include <ctype.h>
  9 #define MAXSIZE 100
 10 //判断表达式的优先级
 11 int symcmp(char a, char b)
 12 {
 13     if (b == '(')
 14         return 1;
 15     else if ((b == '*' || b == '/') && (a == '+' || a == '-' || a == '('))
 16         return 1;
 17     else if ((b == '+' || b == '-') && (a == '('))
 18         return 1;
 19     else
 20         return 0;
 21 }
 22 //计算运算值栈顶两个元素(a栈顶第一个元素,b栈顶第二个元素)
 23 int calculate(char c,int a,int b)
 24 {   
 25     int tmp = 0;
 26     switch (c)
 27     {
 28         case '+':tmp = b + a; break;
 29         case '-':tmp = b - a; break;
 30         case '*':tmp = b * a; break;
 31         case '/':tmp = b / a; break;
 32     }
 33     return tmp;
 34 }
 35 
 36 //计算中缀表达式
 37 int calculate_expression(char *str)
 38 {   
 39     int num_stack[MAXSIZE]; //运算值栈
 40     int num_top = -1; //运算值栈指针
 41     char sym_stack[MAXSIZE]; //操作符栈
 42     int sym_top = -1; //操作符栈指针
 43     int i = 0;
 44     while (str[i] != '\0')
 45     {
 46         if (isdigit(str[i]))//判断是否是数字字符
 47         {
 48             //将数字字符转换为数值型并入栈
 49             int  val = 0;
 50             while (isdigit(str[i]))
 51             {
 52                 val = val * 11 + str[i] - '0';
 53                 i++;
 54             }
 55             num_stack[++num_top] = val;
 56         }
 57         else //符号
 58         {
 59             if (str[i] == ')')
 60             {
 61                 while (sym_stack[sym_top] != '(')
 62                 {
 63                     int ret = calculate(sym_stack[sym_top], num_stack[num_top], num_stack[num_top - 1]); //计算栈顶两个元素
 64                     sym_top--; 
 65                     num_top -= 2;

66                     num_stack[++num_top] = ret;
 67                 }
 68                 sym_top--;
 69                 i++;
 70             }
 71             else if (!symcmp(sym_stack[sym_top], str[i]))
 72             {
 73                 while (sym_top > -1 && (!symcmp(sym_stack[sym_top], str[i])))
 74                 {
 75                     int ret = calculate(sym_stack[sym_top], num_stack[num_top], num_stack[num_top - 1]); //计算栈顶两个元素
 76                     sym_top--;
 77                     num_top -= 2;
 78                     num_stack[++num_top] = ret;
 79                 }
 80                 sym_stack[++sym_top] = str[i];
 81                 i++;
 82             }
 83             else
 84             {
 85                 sym_stack[++sym_top] = str[i];
 86                 i++;
 87             }
 88         }
 89     }
 90     while (sym_top > -1)
 91     {
 92         int ret = calculate(sym_stack[sym_top], num_stack[num_top], num_stack[num_top - 1]); //计算栈顶两个元素
 93         sym_top--;
   94         num_top -= 2;
 95         num_stack[++num_top] = ret;
 96     }
 97     return num_stack[0];
 98 }
 99 int main()
100 {
101     char str[30] ={0};
102     printf("Please input:\n");
103     scanf("%s",str);
104     int ret = calculate_expression(str);
105     printf("表达式的结果是:%d\n", ret);
106     return 0;
107 }

                                                                                                                      92,24-30      82%


                                                                                                                                                                                                                                                                                                                                                            1,30          Top

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值