第二次程序+PSP0级

第二周,老师接着上次的程序有对四则运算的程序,做出来一些要求,这次要求可以控制乘除法,有无括号,控制输出方式,控制结果有无负数,有无余数。

我在对原先的程序分析了一下,发现我原先的程序可扩展性特别差,完全不能再原先的基础上叠加功能,所以我又重新写了一个程序。

思路分析:

1、控制乘除法

2、括号添加。思路:题中只要求添加括号,所以我的括号添加方法是:把所有数放入一个数组中,‘+-*/’都用数字化表示,使用随机函数实现随机选择在哪个运算符左边加上左括号,右括号统一加在右边,其中括号最多只有2层嵌套。

3、判断重复:先生成所有运算式子,然后使用循环判断有无重复。

4、结果有无负数和余数:没任何技巧使用循环里面在加循环,先找到最里面的括号,先乘除再加减,然后消括号重复加减最后得出结果,根据最后结果得出结果。

5、输出方式:使用fstream类把结果输出到1.txt中

  1 #include<iostream>
  2 #include"time.h"
  3 #include<fstream>
  4 #define SUM 1000
  5 #define SUMS 300
  6 using namespace std;
  7 int Results[SUM][SUMS] = { 0 };
  8 
  9 
 10 void Input(int &base, int &top){
 11     cout << "\n请输入下限(正数) ";
 12     cin >> base;
 13     cout << "\n请输入上限(正数) ";
 14     cin >> top;
 15 }
 16 //生成四则运算公式
 17 void Combination1(int time, int base,int top,int add,int dec,int mul,int div,int equ){
 18     int choose;
 19     int amount;
 20     amount = 2 + rand() % 9;
 21     Results[time][0] = 1 + rand() % top;
 22     while (Results[time][0] <= base){
 23         Results[time][0] = 1 + rand() % top;
 24     }
 25     amount--;
 26     int count = 1;
 27     while (true){
 28         choose = 1 + rand() % 4;
 29         if (choose == 1){
 30             Results[time][count] = add;
 31         }
 32         if (choose == 2){
 33             Results[time][count] = dec;
 34         }
 35         if (choose == 3){
 36             Results[time][count] = mul;
 37         }
 38         if (choose == 4){
 39             Results[time][count] = div;
 40         }
 41         count++;
 42         Results[time][count] = 1 + rand() % top;
 43         while (Results[time][count] <= base){
 44             Results[time][count] = 1 + rand() % top;
 45         }
 46         count++;
 47         amount--;
 48         if (amount == 0){
 49             break;
 50         }
 51     }
 52     Results[time][count] = equ;
 53     
 54 }
 55 //生成二则运算公式
 56 void Combination2(int time, int base, int top, int add, int dec, int mul, int div, int equ){
 57     int choose;
 58     int amount;
 59     amount = 2 + rand() % 9;
 60     Results[time][0] = 1 + rand() % top;
 61     while (Results[time][0] <= base){
 62         Results[time][0] = 1 + rand() % top;
 63     }
 64     amount--;
 65     int count = 1;
 66     while (true){
 67         choose = 1 + rand() % 2;
 68         if (choose == 1){
 69             Results[time][count] = add;
 70         }
 71         if (choose == 2){
 72             Results[time][count] = dec;
 73         }
 74         count++;
 75         Results[time][count] = 1 + rand() % top;
 76         while (Results[time][count] <= base){
 77             Results[time][count] = 1 + rand() % top;
 78         }
 79         count++;
 80         amount--;
 81         if (amount == 0){
 82             break;
 83         }
 84     }
 85     Results[time][count] = equ;
 86 }
 87 //cmd
 88 void Output(int time, int top,int add, int dec, int mul, int div, int equ,int LBra,int RBra){
 89     int count = 0;
 90     while (true){
 91         if (Results[time][count] <= top){
 92             cout << Results[time][count];
 93         }
 94         if (Results[time][count] == add){
 95             cout << "+";
 96         }
 97         if (Results[time][count] == dec){
 98             cout << "-";
 99         }
100         if (Results[time][count] == mul){
101             cout << "*";
102         }
103         if (Results[time][count] == div){
104             cout << "/";
105         }
106         if (Results[time][count] == LBra){
107             cout << "(";
108         }
109         if (Results[time][count] == RBra){
110             cout << ")";
111         }
112         if (Results[time][count] == equ){
113             cout << "=";
114             break;
115         }
116         count++;
117     }
118 }
119 //文件流
120 void OutputFile(int time, int top, int add, int dec, int mul, int div, int equ, int LBra, int RBra){
121     ofstream out("1.txt", ios::out);
122     int count;
123         for (int i = 0; i < time; i++){
124             count = 0;
125             while (true){
126                 
127         if (Results[i][count] <= top){
128             out << Results[i][count];
129         }
130         if (Results[i][count] == add){
131             out << "+";
132         }
133         if (Results[i][count] == dec){
134             out << "-";
135         }
136         if (Results[i][count] == mul){
137             out << "*";
138         }
139         if (Results[i][count] == div){
140             out << "/";
141         }
142         if (Results[i][count] == LBra){
143             out << "(";
144         }
145         if (Results[i][count] == RBra){
146             out << ")";
147         }
148         if (Results[i][count] == equ){
149             out << "=";
150             break;
151 
152         }
153         count++;
154         }
155             out << endl;
156     }
157         out.close();
158     
159 }
160 //添加括号
161 void AddBrackets(int time, int add, int dec, int mul, int div, int equ, int LBra,int RBra){
162     int place;
163     int level=0;
164     int sumNum,sumNum1;
165     int count;
166     int BracketNum;
167     BracketNum = 1 + rand() % 2;
168     for (int i = 0; i < SUMS; i++){
169         if (Results[time][i] >= add&&Results[time][i] <= div){
170             level++;
171         }
172         if (Results[time][i] == equ){
173             sumNum = i;
174             break;
175         }
176     }
177     int BracketNum1;
178     BracketNum1 = BracketNum;
179     //随机在运算公式中生成左括号
180     for (int j = 0; j < BracketNum; j++){
181         sumNum1 = sumNum;
182         if (level == 1){
183             break;
184         }
185         place = 1 + rand() % (level - 1);
186         count = 0;
187         while (true){
188             if (Results[time][count] >= add&&Results[time][count] <= div){
189                 place = place - 1;
190                 if (place == 0){
191                     break;
192                 }
193             }
194             count++;
195         }
196         if (Results[time][count + 1] == LBra){
197             BracketNum1--;
198             break;
199         }
200         while (true){
201             Results[time][sumNum + 1] = Results[time][sumNum];
202             if (sumNum - 1 == count){
203                 Results[time][sumNum] = LBra;
204                 break;
205             }
206             sumNum--;
207         }
208         sumNum = sumNum1 + 1;
209     }
210     //直接在等式右边生成相同数量的有括号
211     for (int k = 0; k < BracketNum1; k++){
212         if (level == 1){
213             break;
214         }
215             Results[time][sumNum + 1] = Results[time][sumNum];
216             Results[time][sumNum] = RBra;
217             sumNum++;
218     }
219     if (Results[time][sumNum] != equ){
220         AddBrackets(time, add, dec, mul, div, equ, LBra, RBra);
221     }
222     sumNum1 = sumNum-1;
223     count = 0;
224     while (true){
225         if (Results[time][sumNum1] == RBra){
226             count++;
227         }
228         sumNum1--;
229         if (sumNum1 == sumNum - 3){
230             break;
231         }
232     }
233     sumNum1 = 0;
234     while (true){
235         if (Results[time][sumNum1] == LBra){
236             count--;
237         }
238         if (sumNum1 == sumNum){
239             break;
240         }
241         sumNum1++;
242     }
243     if (count < 0){
244         AddBrackets(time, add, dec, mul, div, equ, LBra, RBra);
245     }
246 }
247 //判断有误重复
248 int Replay(){
249     int i, j,k;
250     int charge;
251     for (i = 0; i < SUM; i++){
252         charge = 0;
253         for (j = i+1; j < SUM; j++){
254             for (k = 0; k < SUMS; k++){
255                 if (Results[i][k] != Results[j][k]){
256                     charge = 1;
257                     break;
258                 }    
259             }
260             if (charge == 0){
261                 return 1;
262             }
263         }
264     }
265     return 0;
266 }
267 
268 //判断有无余数和是否正数
269 //把公式化成float型,有利于进行判断有无余数,而且计算更准确
270 void Judge(int time, int equ, int add, int dec, int mul, int div, int LBra, int RBra, int &pos, int &integer){
271     float calculate[SUMS];
272     int Bracket[2] = { 0 };  //用于记录括号位置
273     int count = 0;
274     int sumNum, sumNum1, sumNum2;
275     for (int i = 0; i < SUMS; i++){
276         if (Results[time][i] == LBra){
277             Bracket[count] = i;
278             count++;
279         }
280         if (count == 2){
281             break;
282         }
283         if (Results[time][i] == RBra){
284             break;
285         }
286     }
287     for (int i = 0; i < SUMS; i++){
288         if (Results[time][i] == RBra){
289             sumNum = i;
290             break;
291         }
292     }
293     for (int i = 0; i < sumNum; i++){
294         calculate[i] = float(Results[time][i]);
295     }
296     int Has = 0;
297     int place;
298     //双括号
299     if (count == 2){
300         sumNum1 = Bracket[1];
301 
302         //sumNum2 = sumNum1;
303         while (true){
304             Has = 0;
305             for (int i = sumNum1 + 1; i < sumNum; i++){
306                 if (calculate[i] == mul)
307                 {
308                     calculate[i - 1] = calculate[i - 1] * calculate[i + 1];
309                     Has = 1;
310                     place = i;
311                     break;
312                 }
313                 if (calculate[i] == div)
314                 {
315                     calculate[i - 1] = calculate[i - 1] / calculate[i + 1];
316                     Has = 1;
317                     place = i;
318                     break;
319                 }
320             }
321             if (Has == 1){
322                 while (true){
323                     if ((place + 2) == sumNum){
324                         break;
325                     }
326                     calculate[place] = calculate[place + 2];
327                     place++;
328 
329 
330                 }
331                 sumNum -= 2;
332             }
333             if (Has == 0){
334                 break;
335             }
336         }
337         sumNum1 += 1;
338         sumNum2 = sumNum1;
339         while (true){
340             if (sumNum1 + 1 >= sumNum){
341                 break;
342             }
343             if (calculate[sumNum1 + 1] == add){
344                 calculate[sumNum2] = calculate[sumNum2] + calculate[sumNum1 + 2];
345                 sumNum1 += 2;
346             }
347             if (calculate[sumNum1 + 1] == dec){
348                 calculate[sumNum2] = calculate[sumNum2] - calculate[sumNum1 + 2];
349                 sumNum1 += 2;
350             }
351         }
352         calculate[sumNum2 - 1] = calculate[sumNum2];
353         sumNum = sumNum2;
354         count = count - 1;
355     }
356     if (count == 1){  //单括号
357         sumNum1 = Bracket[0];
358         while (true){
359             Has = 0;
360             for (int i = sumNum1 + 1; i < sumNum; i++){
361                 if (calculate[i] == mul)
362                 {
363                     calculate[i - 1] = calculate[i - 1] * calculate[i + 1];
364                     Has = 1;
365                     place = i;
366                     break;
367                 }
368                 if (calculate[i] == div)
369                 {
370                     calculate[i - 1] = calculate[i - 1] / calculate[i + 1];
371                     Has = 1;
372                     place = i;
373                     break;
374                 }
375             }
376             if (Has == 1){
377                 while (true){
378                     if ((place + 2) == sumNum){
379                         break;
380                     }
381                     calculate[place] = calculate[place + 2];
382                     place++;
383 
384 
385                 }
386                 sumNum -= 2;
387             }
388             if (Has == 0){
389                 break;
390             }
391         }
392         sumNum1 += 1;
393         sumNum2 = sumNum1;
394         while (true){
395             if (sumNum1 + 1 >= sumNum){
396                 break;
397             }
398             if (calculate[sumNum1 + 1] == add){
399                 calculate[sumNum2] = calculate[sumNum2] + calculate[sumNum1 + 2];
400                 sumNum1 += 2;
401             }
402             if (calculate[sumNum1 + 1] == dec){
403                 calculate[sumNum2] = calculate[sumNum2] - calculate[sumNum1 + 2];
404                 sumNum1 += 2;
405             }
406         }
407         calculate[sumNum2 - 1] = calculate[sumNum2];
408         sumNum = sumNum2;
409     }
410     for (int i = 0; i < sumNum; i++){
411         if (calculate[i] == mul){
412             calculate[i - 1] *= calculate[i + 1];
413             place = i;
414             while (true){
415                 if (place + 2 >= sumNum){
416                     sumNum -= 2;
417                     break;
418                 }
419                 calculate[place] = calculate[place + 2];
420                 place += 1;
421             }
422         }
423         if (calculate[i] == div){
424             calculate[i - 1] /= calculate[i + 1];
425             place = i;
426             while (true){
427                 
428                 if (place + 2 >= sumNum){
429                     sumNum -= 2;
430                     break;
431                 }
432                 calculate[place] = calculate[place + 2];
433                 place += 1;
434             }
435         }
436     }
437     for (int i = 0; i < sumNum; i++){
438         if (calculate[i] == add){
439             calculate[0] = calculate[0] + calculate[i + 1];
440         }
441         if (calculate[i] == dec){
442             calculate[0] = calculate[0] + calculate[i + 1];
443         }
444     }
445     //结果判断
446     if (calculate[0] >= 0){
447         pos = 1;
448     }
449     else{
450         pos = 0;
451     }
452     if ((calculate[0]-int(calculate[0]))!=0)
453     {
454         integer = 0;
455     }
456     else{
457         integer = 1;
458     }
459         
460 }
461 int main(){
462     srand((unsigned)time(NULL));
463     int add;
464     int dec;
465     int mul;
466     int div;
467     int equ;
468     int base;
469     int top;
470     int LBra;
471     int RBra;
472     int MulAndDiv;
473     int HaveBracket;
474     int AboveZero;
475     int Isint;
476     int Isrepeat;
477     int Isfile;
478     int sum;
479     int integer;
480     int pos;
481     cout << "是否使用乘除?1表示是,0表示不是: ";
482     cin >> MulAndDiv;
483     cout << "\n是否有括号?1表示是,0表示不是: ";
484     cin >> HaveBracket;
485     cout << "\n结果能否有负数?1表示能,0表示不能: ";
486     cin >> AboveZero;
487     cout << "\n结果能否有余数? 1表示能,0表示不能: ";
488     cin >> Isint;
489     cout << "请输入题目数量:";
490     cin >> sum;
491     cout << "是否输出到文件? 1表示是,0表示否: ";
492     cin >> Isfile;
493     Input(base, top);
494     add = top + 1;
495     dec = top + 2;
496     mul = top + 3;
497     div = top + 4;
498     equ = top + 5;
499     LBra = top + 6;
500     RBra = top + 7;
501     //判断乘除和有无括号
502     for (int j = 0; j < sum; j++){
503         if (MulAndDiv == 0){
504             Combination2(j, base, top, add, dec, mul, div, equ);
505         }
506         else
507             Combination1(j, base, top, add, dec, mul, div, equ);
508         if (HaveBracket == 1){
509             AddBrackets(j, add, dec, mul, div, equ, LBra, RBra);
510         }
511         
512     }
513     //判断有无负数和余数
514     for (int j = 0; j < sum; j++){
515         pos = 0;
516         integer = 0;
517         Judge(j, equ, add, dec, mul, div, LBra, RBra, pos, integer);
518         if (Isint == 0){
519             while (integer == 0){
520                 if (MulAndDiv == 0){
521                     Combination2(j, base, top, add, dec, mul, div, equ);
522                 }
523                 else
524                     Combination1(j, base, top, add, dec, mul, div, equ);
525                 if (HaveBracket == 1){
526                     AddBrackets(j, add, dec, mul, div, equ, LBra, RBra);
527                 }
528                 Judge(j, equ, add, dec, mul, div, LBra, RBra, pos, integer);
529             }
530         }
531         if (AboveZero == 0){
532             while (pos == 0){
533                 if (MulAndDiv == 0){
534                     Combination2(j, base, top, add, dec, mul, div, equ);
535                 }
536                 else
537                     Combination1(j, base, top, add, dec, mul, div, equ);
538                 if (HaveBracket == 1){
539                     AddBrackets(j, add, dec, mul, div, equ, LBra, RBra);
540                 }
541                 Judge(j, equ, add, dec, mul, div, LBra, RBra, pos, integer);
542             }
543         }
544     }
545         //查重
546     while(true){    
547         if (Replay() == 1){
548             if (Isfile == 1){
549                 OutputFile(sum, top, add, dec, mul, div, equ, LBra, RBra);
550             }
551             else{
552                 for (int j = 0; j < sum; j++){
553                     Output(j, top, add, dec, mul, div, equ, LBra, RBra);
554                     cout << endl;
555                 }
556             }
557             break;
558         }
559         else
560         {
561             for (int j = 0; j < sum; j++){
562                 if (MulAndDiv == 0){
563                     Combination2(j, base, top, add, dec, mul, div, equ);
564                 }
565                 else
566                     Combination1(j, base, top, add, dec, mul, div, equ);
567                 if (HaveBracket == 1){
568                     AddBrackets(j, add, dec, mul, div, equ, LBra, RBra);
569                 }
570 
571             }
572         }
573     }
574     return 0;
575 }

运行结果如下:
cmd输出:

1.txt文件输出:

总结:这一次的实验我感觉蛮难的,我差不多花了4个晚上外加一个星期六才写完,而且这也是勉强实现功能,在编写功能模块时,总是单独测试都运行十分OK,但是几个功能一迭加就老是BUG,然后花1-2小时去调试解决,好麻烦,当然在实现真分数插入括号时老是出现错误,我都不知道该怎么办了-_-!! 总之,这次的程序不能说完美吧,但还是勉强能实现功能。

项目计划总结:

日期\任务 听课 编写程序 查阅资料 日总计
星期一 2 1 1 4
星期二   2   2
星期三   2 1 3
星期四 2 2   4
星期五   3 1 4
星期六   5   5
星期日        
周总计 4 15 3

22

时间记录日志:

日期 开始时间 结束时间 中断时间 静时间 活动 备注
3/7 14:00 15:50 10 100 听课 软件工程
  19:30 21:50 10 130 编写程序 编写第二次程序&查资料
3/8 19:20 21:45 10 135 编写程序  
3/9 16:30 17:40 10 60 查阅资料 查资料和同学间交流
  19:20 21:50 20 130 编写程序  
3/10 14:00 15:50 10 100 听课 软件工程
  19:20 21:20   120 编写程序 调试程序寻找错误地方
3/11 18:10 21:40 20 190 编写程序 调试程序为主
  7:30 9:00 10 80 看书 看数据结构书寻找解决办法
3/12 8:00 15:00 50 370 调试 最终调试
  16:00 17:00   60 博客 撰写博客

缺陷记录日志:

日期 编号 引入阶段 排除阶段 修复时间&问题描述
3/7 1 编码 编译 1小时,真分数叠加,后来发现是输出时除号和正分数符号弄反了
3/8        
3/9        
3/10-3/11 2 编码 编译 4小时,循环叠加混乱,不是忘记赋值就是忘记跳出循环
3/11-3/12 3 编码 编译 4小时,括号添加数量不对,后来发现是数组越界
         

 

posted @ 2016-03-12 17:01  Mr.缪  阅读(187)  评论(1编辑  收藏  举报