发一个自己写的四则运算实现

 

    没什么新意(不仅仅处理个位数算吗?)啦,就是练练手,现在写代码的能里有所下降啊。呵呵 以后每天至少写一段代码,长度>=200吧。

代码
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<ctype.h>
5  //文件实现四则运算,主要原理1:后缀表达式 2:栈的使用
6 //步骤1,将中缀表达式转成后缀(因为这样就可以排除括号,后缀表达不需要括号)
7 //步骤2,根据后缀表达式计算结果
8
9 //优先级分为4级,分为栈内和栈外
10 //inp: */:3 +/-:2 (:1
11 //out: (:4 */:3 +/-:2 ):0
12
13
14 //a是栈顶符号,b是扫描到的符号
15 int compare(const char a,const char b)
16 {
17 int la=0;int lb=0;
18 //注意这里的a是已经在栈内的符号,所以(的优先级就变得最低了,此外不会遇到)因为遇到)的情况都会被处理掉的
19 switch(a)
20 {
21 case '*':case '/':
22 {
23 la = 3;break;
24 }
25 case '+':case'-':
26 {
27 la = 2;break;
28 }
29 case'(':
30 {
31 la =1;break;
32 }
33 default:
34 {
35 printf("unknown symbol in the stack!\n");
36 exit(-1);
37 }
38 }
39 //b是所遇到的表达式里的符号,所以(的优先级最高,并且)的优先级最低,而且一定要处理到第一个匹配的(的位置
40 switch(b)
41 {
42 case'(':
43 {
44 lb=4;break;
45 }
46 case '*':case'/':
47 {
48 lb=3;break;
49 }
50 case'+':case'-':
51 {
52 lb=2;break;
53 }
54 case')':
55 {
56 lb=0;break;
57 }
58 default:
59 {
60 printf("unknown symbol in the expretion!\n");
61 exit(-1);
62 }
63 }
64 return (la-lb);
65 }
66
67
68
69 //将前缀表达式转换为后缀表达式
70 char* trans2back(const char* mid)
71 {
72 int len = strlen(mid);
73 char* copy_mid = (char*)malloc((len+1)*sizeof(char));
74 char* tmp = copy_mid;
75 strcpy(tmp,mid);
76
77 char* stack = (char*)malloc(len*sizeof(char));
78 int top = -1;
79
80 char* rt = (char*)malloc((len*2+1)*sizeof(char));
81 char* back = rt;
82 while(*tmp!='\0')
83 {
84 switch(*tmp)
85 {
86 //遇到符号的情况下(对于‘)’ )我们要特殊处理
87 case'+':case'-':case'*':case'/':case'(':
88 {
89 *back++=' ';//this is for the token between each number
90 if(top==-1)
91 {
92 stack[++top]=*tmp;
93 }
94 else
95 {
96 while(top>=0 && compare(stack[top],*tmp)>=0)
97 {
98 *back++=stack[top];
99
100 top--;
101 }
102 stack[++top]=*tmp;
103 }
104 break;
105 }
106 case ')':
107 {
108 while(top>=0 && stack[top]!='(')
109 {
110 *back++=stack[top--];
111 }
112 if(top<0)
113 {
114 printf("patten error!\n");
115 exit(-1);
116 }
117 top--;
118 break;
119 }
120 default:
121 {
122 *back++=*tmp;
123 break;
124 }
125 }//end of switch
126 tmp++;
127 }//end of while
128 //deal with the left operator
129 if(top >= 0)
130 while(top>=0)
131 {
132 *back++=stack[top--];
133 }
134 *back='\0';
135 free(copy_mid);
136 free(stack);
137 return rt;
138 }
139
140 int isop(char a)
141 {
142 if(a=='*'||a=='/'||a=='+'||a=='-')
143 return 1;
144 else
145 return 0;
146 }
147
148 double op(double a,double b,char op)
149 {
150 switch(op)
151 {
152 case'+':
153 {
154 return a+b;
155 }
156 case '-':
157 {
158 return a-b;
159 }
160 case '*':
161 {
162 return a*b;
163 }
164 case '/':
165 {
166 return a/b;
167 }
168 default:
169 {
170 printf("error int op()\n");
171 exit(-1);
172 }
173 }
174 printf("unknown op in op()\n");
175 exit(-1);
176
177 }
178
179 double caculate(const char* back)
180 {
181 double* stack = (double*)malloc(strlen(back)*sizeof(double));
182 int top=-1;
183 const char* p=back;
184 const char* q=p;
185 double result;
186 while(*q!='\0')
187 {
188 if(isalnum(*q))
189 {
190 p=q;
191 while(isalnum(*q))
192 {
193 q++;
194 }
195 stack[++top]=(double)atoi(p);
196 //printf("add num %lf \n",stack[top]);
197 }
198 else if(*q == ' ')
199 q++;
200 else if(isop(*q))
201 {
202 //printf("the op is %c and the num is %lf and %lf\n",*q,stack[top],stack[top-1]);
203 result = op(stack[top-1],stack[top],*q);
204 stack[--top]=result;
205 q++;
206 }
207 }
208 free(stack);
209 return result;
210 }
211
212
213
214
215
216 int main()
217 {
218 char expression[100];
219 while(1)
220 {
221 fgets(expression,100,stdin);
222 expression[strlen(expression)-1]='\0';
223
224 char* back = trans2back(expression);
225
226 printf("the back expression is %s\n",back);
227
228 printf("the result is %lf\n",caculate(back));
229
230 free(back);
231 }
232 return 0;
233
234 }
235
236
237
238
239
240

现在老忘记事先保存要free掉的指针,然后再去free移动过的指针,所以老是出现一堆core dump...杯具。

另外,c貌似写这些代码的时候很不给力啊,栈实现,字符串处理什么的没有c++来的方便快捷。

posted on 2010-11-08 16:19  Weifeng Wang  阅读(258)  评论(0编辑  收藏  举报

导航