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