//一个能处理四则运算的程序,实现语言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