1 //Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--> //一个能处理四则运算的程序,实现语言C++,支持嵌套括号,可以处理实数,源码见下面:
2 #include<iostream>
3 #include <stdio.h>
4 #include <string.h>
5
6 #include<cmath>
7 using namespace std;
8 const int MAX=1000;
9
10
11
12 class Input
13 {
14 public:
15 Input()
16 {
17 for( int i = 0;i < MAX;i++ )
18 Str_input[i] = '\0';
19 }
20 char Str_input[MAX];
21 }in;
22
23
24 class Output
25 {
26 public:
27 Output()
28 {
29 result = 0;
30 }
31 void getRes( double res )
32 {
33 result = res;
34 }
35 double printRes()
36 {
37 // cout<<"这个表达式的结果为:"<<result<<endl;
38 return result;
39 }
40 private:
41 double result;
42 };
43
44 template <class Type>
45 class STACK{ //定义栈类
46 private:
47 Type base[MAX];
48 int Size;
49 public:
50 STACK(){Size=0;};
51 void push(Type a) //入栈
52 {
53 base[Size]=a;
54 Size++;
55 }
56 Type pop() //出栈
57 {
58 return base[--Size];
59 }
60 int size()
61 {
62 return Size;
63 }
64 };
65
66
67
68 class Calculate_Cla
69 {
70 public:
71 bool IsData(char);
72 bool IsSym(char);
73 int IsPar(char);
74 bool Check(char *);
75 int setPri(char); //判断符号的优先极别
76 double ToData(char*); //把字符串转化为数值
77 double Call(double,double,char); //具体按符号计算
78 int GetMatch(char* buffer,int pos); //利用栈找到匹配的括号
79 void Opr( STACK<char>&, STACK<double>&, int& ); //利用栈计算
80 double Calculate(char*, double& ); //字符串的读入及调配
81
82 };
83 bool Calculate_Cla::IsData(char ch) //判断输入计算的数字是否为0-9 添加科学计数法e
84 {
85 return ((ch>='0'&&ch<='9')||ch=='.'||ch=='e')?true:false;//添加科学计数法e
86 }
87 bool Calculate_Cla::IsSym(char ch) //判断是否输入非法运算符
88 {
89 return (ch=='+'||ch=='-'||ch=='*'||ch=='/')?true:false;
90 }
91 int Calculate_Cla::IsPar(char ch) //判断是否'()'
92 {
93 if(ch=='(')
94 return 1;
95 if(ch==')')
96 return -1;
97 return 0;
98 }
99 bool Calculate_Cla::Check(char *ch)//检验小数点个数,>1报错 l
100 {
101 int a=0;
102 for(int i=0;i<strlen(ch);i++)
103 if(ch[i]=='.')
104 a++;
105 if(a>1)
106 return false;
107 return true;
108 }
109 int Calculate_Cla::setPri(char ch) //符号的优先极别
110 {
111 switch(ch)
112 {
113 case '+':
114 return 0;
115 case '-':
116 return 0;
117 case '*':
118 return 1;
119 case '/':
120 return 1;
121 default:
122 return -1;
123 }
124 }
125 double Calculate_Cla::ToData(char* ch) //将数字转化为数值
126 {
127 int i,j,k,sumn=0;
128 double sum=0.0,p=0.0,q=0.0;
129 int summ=0;//科学计数法所表示的数据e
130 if(!Check(ch)) return 0.0;
131 for(i=0;i<strlen(ch);i++) //读入整数部分
132 {
133 if(ch[i]!='.')
134 sumn=sumn*10+(ch[i]-'0');
135 else break;
136 }
137 if(strchr(ch, 'e')!=NULL)//判断是否为科学计数法e
138 {/////////
139 if(i<strlen(ch))
140 for(j=i+1;j<strlen(ch);j++) //小数部分,到e为止
141 {
142 if(ch[j]!='e')
143 sum=sum*10+(ch[j]-'0');
144 else break;
145 }
146 sum /= pow(10.0,(double)(strlen(ch)-6-i)); //有错
147 if(ch[j]=='e'&&j<strlen(ch))
148 {
149 // if(ch[j]!='\0') //科学计数法部分e
150 for(k=j+2;k<=j+4;k++)
151 summ=summ*10+(ch[k]-'0');// ch[j]的ascii码减去0的ascii码
152 if(ch[j+1]=='-')
153 {
154 double p=(sum+sumn)/pow(10,summ);
155 return ((sum+sumn)/pow(10,summ)); //返回值
156 }
157 if(ch[j+1]=='+')
158 {
159 double q=(sum+sumn)*pow(10,summ);
160 return ((sum+sumn)*pow(10,summ));
161 }
162 }
163 }/////////////////
164 else if(strchr(ch, 'e')==NULL)//如果不含科学计数法e
165 {
166 if(i<strlen(ch))
167 for(j=i+1;j<strlen(ch);j++) //小数部分
168 sum=sum*10+(ch[j]-'0');
169 sum /= pow(10.0,(double)(strlen(ch)-1-i));
170 return (sum+sumn); //返回值
171 }
172 }
173 double Calculate_Cla::Call(double sum,double data,char ch)
174 {
175 double ans=0.0;
176 switch(ch)
177 {
178 case '+':
179 ans=sum+data;
180 break;
181 case '-':
182 ans=sum-data;
183 break;
184 case '*':
185 ans=sum*data;
186 break;
187 case '/':
188 if( data!=0.0 )
189 ans=sum/data;
190 else
191 {
192 cout<<"程序出现除0错误,终止!\n";
193 system("pause");
194 exit(1);
195 }
196 break;
197 default:ans=0.0;
198 break;
199 }
200 return ans;
201 }
202 int Calculate_Cla::GetMatch(char* buffer,int pos) //利用栈找到匹配的括号
203 {
204 STACK<char> Temp;
205 int i;
206 for(i=pos;i<strlen(buffer);i++)
207 {
208 if(IsPar(buffer[i])==1)//左括号l
209 Temp.push('0');
210 if(IsPar(buffer[i])==-1)//右括号l
211 {
212 Temp.pop();//出栈l
213 if(Temp.size()==0) return i;
214 }
215 }
216 return -1;
217 }
218 void Calculate_Cla::Opr(STACK<char>& symbol,STACK<double>& data,int& mark)//运算符操作l
219 {
220 double sum;
221 while(symbol.size()!=0)//运算符栈大小不为0,l
222 {
223 char tem=symbol.pop();//出栈l
224 int temp=setPri(tem);//优先级l
225 symbol.push(tem);//入栈l
226 if(temp<mark)
227 break;
228 else
229 {
230 sum=Call(data.pop(),data.pop(),symbol.pop());
231 data.push(sum);
232 }
233 }
234 }
235 double Calculate_Cla::Calculate(char* buffer,double& sum) //字符串读入和各个函数调配
236 {
237 STACK<double> data;
238 STACK<char> symbol;
239 double ans;
240 char temp[MAX];
241 int ct=0,mark=0,tp=0;
242 data.push(sum);//入栈l
243 while(ct<=strlen(buffer))
244 {
245 if(IsData(buffer[ct])) //如果是数字或小数点
246 {
247 while( ct < strlen(buffer) && IsData(buffer[ct]) )
248 {
249 temp[tp++]=buffer[ct++];
250 }
251 if(temp[tp-1]=='e')
252 {
253 for(int k=0;k<=3;k++)
254 temp[tp++]=buffer[ct++];
255 temp[tp]='\0';
256 }
257 else temp[tp]='\0';
258 tp=0; //读到非数字也非小数为止
259 ans=ToData(temp); //把读到的字符串转化为数
260 data.push(ans); //将数字存入栈中l
261
262 if(ct==strlen(buffer)) //已经独到字符串末尾
263 {
264 mark=0;
265 Opr(symbol,data,mark); //计算
266 sum=data.pop(); //此时data栈中还剩一个数据,即是结果
267 return sum; //返回结果
268 }
269 else
270 {
271 int mark=setPri(buffer[ct]);
272 Opr(symbol,data,mark); //计算
273 }
274 }
275 else if(IsSym(buffer[ct])&&buffer[ct-1]!='e') //如果是运算符且不为指数部分
276 symbol.push(buffer[ct++]); //运算符入symbol栈
277 else
278 {
279 char BF[100];int k=0; //如果都不是,则只能是括号
280 while( IsPar( buffer[ct] )!=1 && ct <= strlen(buffer) )
281 BF[k++] = buffer[ct++];
282 BF[k]='\0';
283 if(IsPar(buffer[ct])==1) //一旦读到左括号,寻找它匹配的右括号
284 {
285 int i,j;
286 char Temp[100];
287 for(i=ct+1,j=0;i<GetMatch(buffer,ct);i++,j++)
288 Temp[j]=buffer[i]; //把这对括号中的字符串存入Temp
289 Temp[j]='\0';
290 data.push(Calculate(Temp,sum)); //递归调用Calculate直到没有括号
291 //然后开始计算,值层层返回最后将最终结果放入data栈
292 ct+=(strlen(Temp)+1); //跳过已经处理完的字符
293 if(ct+1==strlen(buffer)) //这里考虑字符串以括号结尾的情况
294 {
295 mark=0;
296 Opr(symbol,data,mark);
297 sum=data.pop();
298 return sum;
299 }
300 else
301 {
302 mark=setPri(buffer[ct+1]); //不是的话继续计算
303 Opr(symbol,data,mark);
304 }
305 ct++; //读入下一个字符
306 }
307 }
308 }
309 return 0.;
310 }
311
312
313
314 class CheckStr
315 {
316 public:
317 static int check( char *str )
318 {
319 int i;
320 STACK<char> Temp;
321 for( i = 0;i < strlen(str);i++ )
322 {
323 char t = str[i];
324 if( !( (int(str[i]) <= 57 && int(str[i]) >= 48) || str[i]=='(' || str[i]==')' || str[i]=='*'
325 || str[i]=='+' || str[i]=='-' || str[i]=='/' || str[i]=='.'||str[i]=='e') ) //检测是否含有非法字符 添加科学计数法e
326 return 2;
327 else if( str[i]=='(' )
328 Temp.push('0');
329 else if( str[i]==')' )
330 {
331 if( Temp.size()<=0 ) //检测括号是否匹配,右括号是否过多
332 return 1;
333 else
334 Temp.pop();
335 }
336 }
337 if( Temp.size()!=0 ) //检测括号是否匹配,左括号是否过多
338 return 1;
339 return 0;
340 }
341 };
342
343 double function(char*Str_input)//Str_input代入equation[][]
344 {
345 double sum=0.0;
346 cout.precision(12);
347
348 Calculate_Cla cl;
349 Output out;
350
351 while(1)
352 {
353 Str_input;//输入模块
354 int res = CheckStr::check(Str_input); //判断模块 in.Str_input
355 if( res == 0 )
356 break;
357 else if( res == 1 )
358 cout<<"输入字符串括号不匹配,请重新输入:\n";
359 else if( res == 2 )
360 cout<<"输入字符串有非法字符,请重新输入:\n";
361 else
362 {}
363 }
364 out.getRes( cl.Calculate(Str_input,sum) ); //计算模块
365 // out.printRes(); //输出模块
366 system("pause");
367 // return 0;
368 return out.printRes();
369 }
370 void main()
371 {
372 char *fun="12.3e-001+(-4.56e+002)";
373 // char *fun="1.23+(-456)";
374 double C=function(fun);
375 cout<<"这个表达式的结果为:"<<C<<endl;
376 }