簡介:
簡單的 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 }