1 #include<iostream>
2 #include<time.h>
3 using namespace std;
4
5 #define MAXSIZE 100
6
7 typedef struct//栈的储存结构定义
8 {
9 int *base;
10 int *top;
11 int stacksize;
12 }Sqstack;
13
14 int InitStack(Sqstack &S)//为计算构造一个数字空栈
15 {
16 S.base = new int[MAXSIZE];
17 if(!S.base) exit(OVERFLOW);
18 S.top = S.base;
19 S.stacksize = MAXSIZE;
20 return 1;
21 }
22
23 int push(Sqstack &S,int e)//入栈
24 {
25 if(S.top-S.base == S.stacksize) return 0;
26 *S.top++ = e;
27 return 1;
28 }
29
30 int pop(Sqstack &S)//出栈
31 {
32 int e;
33 if(S.top == S.base) return 0;
34 e = *--S.top;
35 return e;
36 }
37
38 int gettop(Sqstack S)//取栈顶元素
39 {
40 if(S.top != S.base)
41 return *(S.top - 1);
42 }
43
44 int getsecondtop(Sqstack S)//取次栈顶元素
45 {
46 if(S.top != S.base)
47 return *(S.top - 2);
48 }
49
50 int z[30][7],x[30][11];
51
52 int output(int a,int b,int c,int d,int e)//分数输出
53 {
54 for(int i = a;i > 1;i--)
55 {
56 if(a % i == 0 && b % i == 0)
57 {
58 a = a / i;
59 b = b / i;
60 break;
61 }
62 }
63 for(int i = c;i > 1;i--)
64 {
65 if(c%i == 0 && d % i == 0)
66 {
67 c = c / i;
68 d = d / i;
69 break;
70 }
71 }
72 switch(e)
73 {
74 case 0 : cout<<"("<<a<<"/"<<b<<")"<<"+"<<"("<<c<<"/"<<d<<")"<<"=?";break;
75 case 1 : cout<<"("<<a<<"/"<<b<<")"<<"-"<<"("<<c<<"/"<<d<<")"<<"=?";break;
76 case 2 : cout<<"("<<a<<"/"<<b<<")"<<"*"<<"("<<c<<"/"<<d<<")"<<"=?";break;
77 case 3 : cout<<"("<<a<<"/"<<b<<")"<<"/"<<"("<<c<<"/"<<d<<")"<<"=?";break;
78 }
79 return 1;
80 }
81
82 int fenshu_zhengquejieguo(int a,int b,int c,int d,int e)
83 {
84 switch(e)
85 {
86 case 0: return(int (a * d + c * b) / (b * d)); break;
87 case 1: return(int (a * d - c * b) / (b * d));break;
88 case 2: return(int (a * c) / (b * d));break;
89 case 3: return(int (a * d) / (b * c));break;
90 }
91 return 1;
92 }
93
94 int zhengshu_zhengquejieguo(int *a)
95 {
96 Sqstack Shuzi,Fuhao;//声明
97 InitStack(Shuzi);//初始化
98 InitStack(Fuhao);//初始化
99 int e,c,p,e2,q;
100 for(int i = 0;i < 7;i++)
101 {
102 if(i%2 == 1)//如果是符号压入符号栈
103 {
104 push(Fuhao,a[i]);
105 }
106 else//否则压入数字栈
107 {
108 push(Shuzi,a[i]);
109 }
110
111 if(i > 1 &&gettop(Fuhao) > 1 && i % 2 == 0)//如果从左向右遇见乘除法就直接执行
112 {
113 e = pop(Fuhao);
114 c = pop(Shuzi);
115 p = pop(Shuzi);
116 switch(e)
117 {
118 case 2: push(Shuzi,(c*p));break;
119 case 3: push(Shuzi,(p/c));break;
120 }
121 }
122
123 if(i > 3 && gettop(Fuhao) < 2 && getsecondtop(Fuhao) < 2 && Fuhao.top - Fuhao.base > 1 && i % 2 == 0)//如果遇见连续的两个加减法执行第一个
124 {
125 e = pop(Fuhao);
126 e2 = pop(Fuhao);
127 c = pop(Shuzi);
128 p = pop(Shuzi);
129 q = pop(Shuzi);
130 switch(e2)
131 {
132 case 0: push(Shuzi,(q + p));break;
133 case 1: push(Shuzi,(q - p));break;
134 }
135 push(Shuzi,c);
136 push(Fuhao,e);
137 }
138 }
139
140 if(Shuzi.top != Shuzi.base)//最终肯定会剩下一组数还有最后一次加减运算
141 {
142 e = pop(Fuhao);
143 c = pop(Shuzi);
144 p = pop(Shuzi);
145
146 switch( e )
147 {
148 case 0: push(Shuzi,(p + c));break;
149 case 1: push(Shuzi,(p - c));break;
150 }
151 }
152
153 return gettop(Shuzi);
154
155 }
156
157 int panduanchongfu(int *a,int ma,int mi,int y)
158 {
159 //---------------------------------------------用来判断是不是完全相同-----------------------------------------------------
160 int m = 1;
161 while(m == 1)
162 {
163 for(int j = 0;j < y;j++)
164 {
165 if(a[0]==z[j][0]&&a[1]==z[j][1]&&a[2]==z[j][2]&&a[3]==z[j][3]&&a[4]==z[j][4]&&a[5]==z[j][5]&&a[6]==z[j][6])
166 {
167 srand((unsigned)time(NULL));
168 a[0] = rand() % ma + mi;
169 z[y][0] = a[0];
170
171 a[1] = rand() % ma + mi;
172 z[y][1] = a[1];
173 break;
174 }
175
176 if( j == ( y - 1 ) )
177 {
178 m = 0;
179 }
180 }
181 }
182 //----------------------------------------------判断加法出现时候是不是完全相同------------------------------------------------------------
183 while(m == 1)
184 {
185 for(int j = 0;j < y;j++)
186 {
187 if(a[1]==0&&a[3]==z[j][3]&&a[4]==z[j][4]&&a[5]==z[j][5]&&a[6]==z[j][6]&&a[0]==a[2]&&a[3]<2)//加法在第一位,并且旁边两个数换了位置
188 {
189 srand((unsigned)time(NULL));
190 a[0] = rand() % ma + mi;
191 z[y][0] = a[0];
192 break;
193 }
194
195 if( j == ( y - 1 ) )
196 {
197 m = 0;
198 }
199 }
200 }
201 //----------------------------------------------判断乘法出现时候是不是完全相同------------------------------------------------------------
202 /*while(m == 1)
203 {
204 for(int j = 0;j < y;j++)
205 {
206
207
208 if( j == ( y - 1 ) )需要注意,这几种情况 一个乘号 1.在第一位 2*3 和 3*2 2.在第二位 前边没有乘除法 3.在第三位,第二位没有乘除法
209 { 两个乘号 1.在前两个 1*2*3 和 3*2*1 和 2*3*1 等六种情况 2.在后两个,前边不是乘除法
210 m = 0; 三个乘号
211 }
212 }
213 }*/
214 //---------------------------------------------加法和乘法除法相邻出现并且重复---------------------------
215 /*加法连接乘除法 1+2*3 == 2*3+1
216 */
217 return 1;
218 }
219
220 int tiaojianpanduan(int *a,int y,int ma,int mi)//整数输出
221 {
222 for(int i = 0;i < 7;i++)
223 {
224 if(i%2 == 0)//挑出数字,如果直接筛选出符号那么不能修改之前的数字
225 {
226 //---------------------------------------------------------------------------------------------------------------------------------------
227 while(a[i] == 0)//判断被除数为0的情况
228 {
229 while(i > 0 && a[i - 1] == 3)
230 {
231 srand((unsigned)time(NULL));
232 a[i] = rand() % ma + mi;
233 z[y][i] = a[i];//更新原来数组
234 }
235 }
236 if(a[ i + 1 ] == 2)//出现除法前边有乘法的情况,首先计算出乘法的结果
237 {//并且根据概率更新除法参与运算数的情况有可能永远不能实现结果为真分数,所以更新乘法参与运算数
238 if(a[ i + 3 ] == 3)
239 {
240 while(a[i] * a[i+2] > a[i+4])
241 {
242 srand((unsigned)time(NULL));
243 a[i+2] = rand() % ma + mi;
244 z[y][i+2] = a[i+2];//更新原来数组
245 }
246 }
247 }
248 if(a[i+1] == 3&&a[i-1] != 2)//有除法,其中包括只有一个除法,还有连续好几个除法,但是通过改变后一个数的规律可以有效的解决这个问题
249 {
250 while(a[i] > a[i + 2])
251 {
252 srand((unsigned)time(NULL));
253 a[i+2] = rand() % ma + mi;
254 z[y][i+2] = a[i+2];//更新原来数组
255 }
256 }
257 //--------------------------------------此上是处理出现除法的情况,此下是减法---------------------------------------------------------------
258 if(a[i+1]==1)//出现减法的情况
259 {
260 if(i + 1 ==5 && a[i-3]==3 && a[i-1]==2 && a[i-4]/a[i-2]*a[i] < a[i+2])//减法在最后一个符号位置,并且前边是除法连接乘法
261 {
262 while(a[i-4]/a[i-2]*a[i]<mi)//前边计算出来的数字之和小于随机生成数的最小值,那么就更新最后一个数字和乘法的后一个数字
263 {
264 srand((unsigned)time(NULL));
265 a[i] = rand() % ma + mi;
266 a[i+2] = rand() % ma + mi;
267 z[y][i] = a[i];//更新原来数组
268 z[y][i+2] = a[i+2];//更新原来数组
269
270 }
271 while(a[i-4]/a[i-2]*a[i] >= mi)//如果大于最小值,那么只需要更新减数
272 {
273 srand((unsigned)time(NULL));
274 a[i+2] = rand() % ma + mi;
275 z[y][i+2] = a[i+2];//更新原来数组
276 }
277 }
278 if(a[i-1]==3 && i+1==3)//除法出现在减法前边一个符号,将减法变为加法.只有减法在第二个符号时有效
279 {
280 a[i+1]=0;
281 z[y][i+1] = a[i+1];//更新原来数组
282 }
283 //此上两种情况是处理除法和减法同时出现并且互相影响的情况
284 //减号附近有没有乘除法,提前计算
285 switch(i+1)
286 {
287 case 1://减法在第一位的情况
288 if(a[i+3]==2 && a[i+5]<2)//- * _ 因为前一步已经将除法得数化为真分数,所以不用考虑除法的情况
289 {
290 while(a[i]-a[i+2]*a[i+4]<0)
291 {
292 srand((unsigned)time(NULL));
293 a[i+2] = rand() % ma + mi;
294 z[y][i+2] = a[i+2];//更新原来数组
295 a[i+4] = rand() % ma + mi;
296 z[y][i+4] = a[i+4];//更新原来数组
297 }
298 }
299 if(a[i+3]==2 && a[i+5]==2)//- * *同上步解释,不用考虑先乘后初的情况
300 {
301 while(a[i]-a[i+2]*a[i+4]*a[i+6]<0)
302 {
303 srand((unsigned)time(NULL));
304 a[i+2] = rand() % ma + mi;
305 z[y][i+2] = a[i+2];//更新原来数组
306 a[i+4] = rand() % ma + mi;
307 z[y][i+4] = a[i+4];//更新原来数组
308 a[i+6] = rand() % ma + mi;
309 z[y][i+6] = a[i+6];//更新原来数组
310 }
311 }
312 if(a[i+3]==2 && a[i+5]==2)//- / *
313 {
314 while(a[i]-a[i+2]/a[i+4]*a[i+6]<0)
315 {
316 srand((unsigned)time(NULL));
317 a[i+2] = rand() % ma + mi;
318 z[y][i+2] = a[i+2];//更新原来数组
319 a[i+4] = rand() % ma + mi;
320 z[y][i+4] = a[i+4];//更新原来数组
321 a[i+6] = rand() % ma + mi;
322 z[y][i+6] = a[i+6];//更新原来数组
323 }
324 }break;
325 case 3://减法在第二位的情况
326 if(a[i-1]==2&&a[i+3]==2)//* - *
327 {
328 while(a[i-2]*a[i]<a[i+2]*a[i+4])
329 {
330 srand((unsigned)time(NULL));
331 a[i+2] = rand() % ma + mi;
332 z[y][i+2] = a[i+2];//更新原来数组
333 a[i+4] = rand() % ma + mi;
334 z[y][i+4] = a[i+4];//更新原来数组
335 }
336 }
337 if(a[i+3]==2 && a[i-1]==0)//+ - *
338 {
339 while( ( a[i-2] + a[i] ) < ( a[i+2] * a[i+4] ) )
340 {
341 srand( ( unsigned ) time( NULL ) );
342 a[i+2] = rand() % ma + mi;
343 z[y][i+2] = a[i+2];//更新原来数组
344 a[i+4] = rand() % ma + mi;
345 z[y][i+4] = a[i+4];//更新原来数组
346 }
347 }
348 if(a[i+3]==2 && a[i-1]==1)//- - *
349 {
350 while( ( a[i-2] - a[i] ) < ( a[i+2] * a[i+4] ) )
351 {
352 srand( ( unsigned ) time( NULL ) );
353 a[i+2] = rand() % ma + mi;
354 z[y][i+2] = a[i+2];//更新原来数组
355 a[i+4] = rand() % ma + mi;
356 z[y][i+4] = a[i+4];//更新原来数组
357 }
358 }
359 if(a[i+3]<2 && a[i-1]==2)//* - _
360 {
361 while(a[i-2]*a[i]<a[i+2])
362 {
363 srand((unsigned)time(NULL));
364 a[i+2] = rand() % ma + mi;
365 z[y][i+2] = a[i+2];//更新原来数组
366 }
367 }
368 case 5://减法在第三位的情况
369 if(a[i-3]==2&&a[i-1]==2)//* * -
370 {
371 while(a[i-4]*a[i-2]*a[i]<a[i+2])
372 {
373 srand((unsigned)time(NULL));
374 a[i+2] = rand() % ma + mi;
375 z[y][i+2] = a[i+2];//更新原来数组
376 a[i] = rand() % ma + mi;
377 z[y][i] = a[i];//更新原来数组
378 }
379 }
380 if(a[i-3]==0&&a[i-1]==2)//+ * -
381 {
382 while(a[i-4]+a[i-2]*a[i]<a[i+2])
383 {
384 srand((unsigned)time(NULL));
385 a[i+2] = rand() % ma + mi;
386 z[y][i+2] = a[i+2];//更新原来数组
387 a[i] = rand() % ma + mi;
388 z[y][i] = a[i];//更新原来数组
389 }
390 }
391 if(a[i-3]==1&&a[i-1]==2)//- * -
392 {
393 while(a[i-4]-a[i-2]*a[i]<a[i+2])
394 {
395 srand((unsigned)time(NULL));
396 a[i+2] = rand() % ma + mi;
397 z[y][i+2] = a[i+2];//更新原来数组
398 }
399 }
400 if(a[i-3]==0&&a[i-1]==3)//+ / -
401 {
402 while(a[i-4]+a[i-2]/a[i]<a[i+2])
403 {
404 srand((unsigned)time(NULL));
405 a[i+2] = rand() % ma + mi;
406 z[y][i+2] = a[i+2];//更新原来数组
407 a[i] = rand() % ma + mi;
408 z[y][i] = a[i];//更新原来数组
409 }
410 }
411 if(a[i-3]==1&&a[i-1]==3)//- / -
412 {
413 while(a[i-4]-a[i-2]/a[i]<a[i+2])
414 {
415 srand((unsigned)time(NULL));
416 a[i+2] = rand() % ma + mi;
417 z[y][i+2] = a[i+2];//更新原来数组
418 }
419 }
420 }
421 while(a[i]<a[i+2])
422 {
423 srand((unsigned)time(NULL));
424 a[i+2] = rand() % ma + mi;
425 z[y][i+2] = a[i+2];//更新原来数组
426 }
427 }
428 }
429 }
430 return 1;
431 }
432
433 int shuchu(int *a,int y,int ma,int mi)//整数输出
434 {
435 for(int i = 0;i < 7;i++)
436 {
437 if(i%2 == 0)//挑出数字
438 {
439 cout<<a[i];
440 }
441 else
442 {
443 switch(a[i])
444 {
445 case 0: cout << "+"; break;
446 case 1: cout << "-"; break;
447 case 2: cout << "*"; break;
448 case 3: cout << "/";
449 }
450 }
451 }
452 cout<<endl;
453 return 1;
454 }
455
456 int main()
457 {
458 int y = 0,p = 0,suijishu[7],m=1;
459 int number_amount,number_jisuanshileixing,number_daduishu=0;
460 int ma,mi;
461 int tiaojian_cheng,tiaojian_jia;;
462 int kehu_jieguo;
463
464 srand((unsigned)time(NULL));//产生随机种子
465 cout << "请选择是整数运算还是真分数运算(1.整数,2分数)";
466
467 cin >> number_jisuanshileixing;
468
469 if(number_jisuanshileixing == 1)
470 {
471 cout << "数值范围?(最大和最小)";
472 cin >> ma;
473 cin >> mi;
474
475 cout << "生成多少个式子?";
476 cin >> number_amount;
477
478 cout << "是否有乘除法(1.可以有0.没有)";
479 cin >> tiaojian_cheng;
480
481 for(int i = 0;i < number_amount;i++)
482 {
483 cout << "题目" << i+1 << "为:";
484 for(int i = 0 ; i < 7 ; i++)//生成随机数还有符号
485 {
486 if(i%2==0)
487 {
488 suijishu[i]=rand()%ma+mi;
489 }
490 else
491 {
492 suijishu[i]=rand()%4;//产生加减乘除四种情况
493 if(tiaojian_cheng == 0)
494 {
495 suijishu[i]=rand()%2;
496 }
497 }
498 z[y][i] = suijishu[i];
499 }
500
501 tiaojianpanduan(suijishu,y,ma,mi);
502
503 if(y > 0)
504 {
505 panduanchongfu(suijishu,ma,mi,y);
506 }
507
508 y++;
509
510 shuchu(suijishu,y,ma,mi);
511
512 cout << "请输入正确结果:";
513 cout << endl;
514 cin >> kehu_jieguo;
515
516 if(kehu_jieguo == zhengshu_zhengquejieguo(suijishu))
517 {
518 cout << "输入正确!";
519 number_daduishu++;
520 cout << "正确结果为" << zhengshu_zhengquejieguo(suijishu) << endl;
521 }
522 else
523 {
524 cout << "输入错误!";
525 cout << "正确结果为" << zhengshu_zhengquejieguo(suijishu) << endl;
526 }
527 }
528 cout<<"您一共答对了"<<number_daduishu<<"道题";
529 }
530 else if(number_jisuanshileixing==2)
531 {
532 cout<<"生成多少个式子?";
533 cin>>number_amount;
534
535 cout<<"是否有乘除法(0.没有1.可以有)";
536 cin>>tiaojian_cheng;
537
538 cout<<"加减是否能得负数(0.不能1.能)";
539 cin>>tiaojian_jia;
540
541 for(int i=0;i<number_amount;i++)
542 {
543 int frist_fenzi=rand()%100;
544 int first_fenmu=rand()%100;
545 int second_fenzi=rand()%100;
546 int second_fenmu=rand()%100;
547
548 int fuhao=rand()%4;
549 if(p>0)
550 {
551 while(m==1)
552 {
553 for(int j=0;j<p+1;j++)
554 {
555 if(frist_fenzi==x[j][1]&&first_fenmu==x[j][2]&&second_fenzi==x[j][3]&&second_fenmu==x[j][3]&&fuhao==x[j][3])
556 {
557 srand((unsigned)time(NULL));
558 frist_fenzi=rand()%100;
559 srand((unsigned)time(NULL));
560 second_fenzi=rand()%100;
561 break;
562 }
563 if(j==p)
564 {
565 m=0;
566 }
567 }
568 }
569 }
570
571 x[p][1]=frist_fenzi;
572 x[p][2]=first_fenmu;
573 x[p][3]=second_fenzi;
574 x[p][4]=second_fenmu;
575 if(tiaojian_cheng == 0)//处理有无乘除法
576 {
577 fuhao=rand()%2;
578 }
579
580 x[p][5]=fuhao;
581
582 p++;
583
584 if(first_fenmu==0)//去掉分母为零的情况
585 {
586 first_fenmu=rand()%100;
587 }
588 if(second_fenmu==0)
589 {
590 second_fenmu=rand()%100;
591 }
592
593 if(frist_fenzi>first_fenmu)//调整为真分数
594 {
595 int x;
596 x=first_fenmu;
597 first_fenmu=frist_fenzi;
598 frist_fenzi=x;
599 }
600
601 if(second_fenzi>second_fenmu)//调整为真分数
602 {
603 int x;
604 x=second_fenzi;
605 second_fenzi=second_fenmu;
606 second_fenmu=x;
607 }
608
609 switch(fuhao)
610 {
611 case 0: output(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao);break;
612
613 case 1:
614 if(tiaojian_jia==0)
615 {
616 while((double(frist_fenzi/first_fenmu)-double(second_fenzi/second_fenmu))<0)
617 {
618 srand((unsigned)time(NULL));
619 frist_fenzi=rand()%100;
620 second_fenzi=rand()%100;
621 }
622 }
623 output(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao);break;
624
625 case 2: output(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao);break;
626
627 case 3: output(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao);break;
628
629 }
630 cout<<endl;
631 cout<<"请输入正确结果:";
632 cin>>kehu_jieguo;
633 if(kehu_jieguo==fenshu_zhengquejieguo(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao))
634 {
635 cout<<"输入正确!"<<endl;
636 number_daduishu++;
637 cout<<"正确结果为"<<fenshu_zhengquejieguo(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao)<<endl;
638 }
639 else
640 {
641 cout<<"输入错误"<<endl;
642 cout<<"正确结果为"<<fenshu_zhengquejieguo(frist_fenzi,first_fenmu,second_fenzi,second_fenmu,fuhao)<<endl;
643 }
644 cout<<endl;
645 m=1;
646 }
647 cout<<"您一共答对了"<<number_daduishu<<"道题";
648 }
649 return 1;
650 }