简介:
简单的 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 }