07_简单的LISP加减乘除(基本计算器)

简介:

简单的 LISP 加减乘除语句解析并计算结果,四种运算符号为 add、sub、mul、div,分别为加减乘除。其中数字部分皆为整数。除法取整,除数为零输出 error。试题出处

例子:

(add 3 5 7) 结果为 15
(sub 1 9) 结果为 -8
(mul 0 9) 结果为 0
(div 8 3) 结果为 2
(div 8 0) 结果为 error
(add (sub (div 8 2) (mul 1 9)) 20) 结果为 15

解题思路:

解出这题的想法是来自labuladong的基本计算器题解,我做的工作就是把他所讲述的过程翻译成C,大佬的想法还真是通用,这不,在这道题目上仍然可以使用,多的一步操作就是需要先将题目中的形式转变成正常四则运算的形式,转换之后就可以开心的套用模板了。

示例程序:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include <ctype.h>
  5 
  6 /*
  7  * 翻译成常规的四则运算表达式
  8  */
  9 void parse(char *str)
 10 {
 11     char sign = 0;
 12     char *p = NULL;
 13 
 14     while (1) {
 15     p = strrchr(str, '(');
 16     if (p != NULL) {
 17         *p = 'l';
 18         switch (*++p) {
 19             case 'a':
 20                 sign = '+';    
 21                 break;
 22             case 's':
 23                 sign = '-';
 24                 break;
 25             case 'm':
 26                 sign = '*';
 27                 break;
 28             case 'd':
 29                 sign = '/';
 30                 break;
 31         }
 32         memset(p, '@', 4);
 33         p += 4;
 34         while (*p != ')') {
 35             if (*p == ' ')
 36                 *p = sign;
 37             p++;
 38         }
 39         *p = 'r';
 40     } else {
 41         break;
 42     }
 43     }
 44 
 45     p = str;
 46     while (*p) {
 47         if (*p == 'l')
 48             *p = '(';
 49         else if (*p == 'r')
 50             *p = ')';
 51         else if (*p == '@')
 52             *p = ' ';
 53 
 54         p++;
 55     }
 56 }
 57 
 58 /*
 59  * 计算四则运算表达式的结果,处理括号时会涉及到递归
 60  */
 61 int calcu(char **s)
 62 {
 63     int pre = 0;
 64     int num = 0;
 65     int top = 0;
 66     char sign = '+';
 67     char *p = NULL;
 68     char c = 0;
 69 
 70     int stack[1000] = {0};
 71 
 72     while (1) {
 73         c = **s;
 74         if (isdigit(c))
 75             num = num*10 + (c-'0');
 76 
 77         if (c == '(') {
 78             *s += 1;
 79             num = calcu(s);
 80             while(*(*s)++ != ')');
 81             c = **s;
 82         }
 83 
 84         if (!isdigit(c) && c != ' ') {
 85             switch (sign) {
 86                 case '+':
 87                     num = num;
 88                     break;
 89                 case '-':
 90                     num = -num;
 91                     break;
 92                 case '*':
 93                     pre = stack[--top];
 94                     num = pre * num;
 95                     break;
 96                 case '/':
 97                     pre = stack[--top];
 98                     num = pre / num;
 99                     break;
100             }
101             stack[top++] = num;
102             num = 0;
103             sign = c;
104         }
105         
106         if (!c || c==')') {
107             while (top > 0)
108                 num += stack[--top];
109             break;
110         }
111 
112         (*s)++;
113     }
114 
115     return num;
116 }
117 
118 int main()
119 {
120     char s[] = "(add (sub (div 8 2) (mul 1 9)) 20 1)"; //"(div (add (sub (div 8 2) (mul 1 9)) 20) (div 6 (add 1 1)))";
121     char *p = s;
122     int num = 0;
123 
124     parse(s);
125     puts(s);
126 
127     num = calcu(&p);
128     printf("final num: %d.\n", num);
129 
130     return 0;
131 }

 

posted @ 2020-10-11 00:30  Zackary丶Liu  阅读(875)  评论(0编辑  收藏  举报