结对开发——四则运算(三)

一、题目及题目要求

      编程随机生成四则运算,算数包括整数和真分数

1.题目避免重复

2.可定制(数量/打印方式)

3.可以控制下列参数:

          是否有乘除法;

          是否有括号(最多可以支持十个数参与运算);

          数值范围;

          加减有无负数;

          除法有无余数。

4.输入结果并判断正确

二、设计思路

   在上次程序的基础上进行修改,

    1.题目避免重复:为避免随机数每次相同用了srand函数。

    2.可定制出题数量:通过键盘输入数字,在for循环中控制循环次数。

   3. 是否有乘除法:把算符分为两大类,利用case语句选择前四种加和减,后四种乘除。

   4. 数值范围:在产生随机数时通过输入控制rand函数的参数,从而使运算数不超过此范围。

   5. 加减有无负号:结果无负数,判断两操作数,第一操作数若比第二操作数小,则第二个减第一个。

   6.除法有无余数:除法无余数,判断第一操作数模第二操作数的结果,若为0即可输出,否则再循环一次。

   7.是否有括号:先随机生成一个数字,代表着生成表达式中操作数的个数。再循环生成一个数字,将其输出,然后等概率生成‘+’‘-’‘*’‘/’中的一个跟在该数字后面,输出。以一定概率生成左括号,若生成了左括号则输出,并进行计数标志当前共有多少个未完成匹配的左括号。若当前有未完成匹配的左括号,则在生成一个数字后,生成一个操作符前,以一定的概率生成右括号。在生成完毕后,生成最后一个数并将为匹配的左括号予以匹配。把产生的式子存入文件。

   8.输入结果并判断正确:(1)对于两个运算数的式子,把结果存入数组,调用函数与数组中的值比较。

                                 (2)对于多个运算数的式子,从文件中读取内容,利用中缀表达式转换为后缀表达式,然后就是后缀表达式的计算,最后与用户输入结果对比。

三、代码

  1 #include<iostream>
  2 #include<ctime>
  3 #include<stack>
  4 #include<fstream>
  5 #define length 10000//存放答案数组长度
  6 using namespace std;
  7 typedef long long ll;
  8 ofstream fout("equation.txt");
  9 char Op[] = {'+', '-', '*', '/'};
 10 int rights;//对题数目
 11 int wrong;//错题数目
 12 
 13 struct num{
 14     ll numerator, denominator;
 15     num(){numerator = 0; denominator = 1;}
 16     num(int n) {numerator = n; denominator = 1;}
 17     num(int n,int d) {numerator = n; denominator = d;}
 18     
 19     void operator = (num x)
 20     {
 21         numerator = x.numerator;
 22         denominator = x.denominator;
 23     }
 24 };
 25 #define maxl 1005
 26 char nifix[maxl], post[maxl];
 27 char ans[maxl];
 28 int cnt_right, cnt_wrong;
 29 bool error;
 30 num res, rst;
 31 
 32 //****分数类***//
 33     class fraction
 34     {
 35      private:
 36         int above;         //分子
 37         int below;         //分母
 38         void reduction();            //约分
 39         fraction makeCommond(fraction); //通分
 40  
 41     public:
 42         fraction()
 43         {             //构造函数
 44         }
 45        fraction add(fraction);      //两分数相加
 46        fraction sub(fraction);      //两分数相减
 47        fraction mul(fraction);      //两分数相乘
 48        fraction div(fraction);      //两分数相除
 49        int display(int,int);              //显示分数
 50        void setvalue(int ,int);                //存储分数
 51     };
 52 
 53 //***********分数的约分*********//
 54 
 55       void fraction::reduction()
 56       {
 57         int i,comdiv,small,max;
 58         if(above<below)
 59         {
 60           small=above;
 61           max=below;
 62          }
 63         else
 64         {
 65           small=below;
 66           max=above;
 67         }
 68        for(i=small;i>1;i--)
 69        {
 70           if((small%i==0 )&(max%i==0) )
 71           break;
 72        }
 73          comdiv=i;            //最大公约数
 74 
 75           if(i!=0)
 76           {
 77               above/=i;
 78               below/=i;
 79            }
 80     }
 81 
 82  //*************分数的通分*************//
 83 
 84     fraction fraction::makeCommond(fraction frac)
 85     {
 86        int b1=below,b2=frac.below, m,s;
 87        if(b1>b2)
 88        {
 89         m=b1%b2;
 90         s=b2;
 91        }
 92         else
 93         {
 94           m=b2%b1;
 95           s=b1;
 96         }
 97        while(m>0)
 98        {
 99          int res=s%m;
100           s=m,m=res;
101        }
102        int small=(b1*b2)/s;
103        above=above*(small/below);
104        frac.above=frac.above*(small/frac.below);
105        below=small;
106        frac.below=small;
107        return frac;
108     }
109    //***************分数的相加*************//
110 
111     fraction fraction::add(fraction fr)
112     {
113           fraction myFraction;
114           myFraction.above=above*fr.below+fr.above*below;
115           myFraction.below=below*fr.below;
116           myFraction.reduction();
117           return myFraction;
118     }
119 //*********************分数的相减***************//
120 
121      fraction fraction::sub(fraction fr)
122      {
123            fraction myFraction;
124            myFraction.above=above*fr.below-fr.above*below;
125            myFraction.below=below*fr.below;
126            myFraction.reduction();
127            return myFraction;
128     }
129 
130   //*******************分数的相乘****************//
131 
132     fraction fraction::mul(fraction fr)
133     { 
134           fraction myFraction;
135           myFraction.above=above*fr.above;
136           myFraction.below=below*fr.below;
137           myFraction.reduction();
138           return myFraction;
139     } 
140 //******************分数的相除***********//
141 
142     fraction fraction::div(fraction fr)
143     {
144         fraction myFraction; 
145         myFraction.above=above*fr.below;
146         myFraction.below=below*fr.above;
147         myFraction.reduction();
148         return myFraction;
149     }
150 
151  //*********************分数答案的输入判断*************//
152 
153     int fraction::display(int a,int b)
154     {
155     
156         if((a==above)&&(b==below))
157         {
158             cout<<"正确"<<endl;
159             rights=rights+1;
160         }
161         else
162         {
163             cout<<"错误"<<endl;
164             wrong=wrong+1;
165         }
166         return rights,wrong;
167     } 
168 
169   //*******************分数的赋值****************//
170 
171      void fraction::setvalue(int sj1,int sj3)           
172      { 
173         above=sj1;
174         below=sj3;
175     }
176 //*************无分数,无余数答案判断****************//
177     
178      int answer(int a[],int i)
179     {
180         int ans;
181         
182         cout<<"请输入答案:"<<endl;
183         cin>>ans;
184           if(ans==a[i]) 
185           {
186               cout<<"正确"<<endl;
187               rights=rights+1;
188             }
189           else
190           {
191               cout<<"错误"<<endl;
192               wrong=wrong+1;
193           }
194           return rights,wrong;
195      
196     }
197  //*************无分数,有余数答案判断****************//
198     int answer_1(int a[],int i,int b[])
199     {
200         int ans,yushu;
201         
202         cout<<"请输入商:"<<endl;
203         cin>>ans;
204         cout<<"输入余数"<<endl;
205         cin>>yushu;
206           if((ans==a[i])&&(yushu=b[i])) 
207           {
208               cout<<"正确"<<endl;
209                rights=rights+1;
210             }
211           else
212           {
213               cout<<"错误"<<endl;
214               wrong=wrong+1;
215           }
216           return rights,wrong;
217      
218     }
219  //*************产生带括号式子****************//
220     void create(int maxn)
221     {
222         
223         if(!fout)                        //如果打开失败,outfile返回值
224         {
225           cerr << "open error!" << endl;
226          exit(1);
227         }
228 
229     //首先随机生成算式中操作数的个数,其数量必须大于1 
230     int lengt;//式子长度
231     do{
232         lengt = rand()%8;
233     }while(lengt < 2);
234     bool div = false;                        //用来防止出现除0错误 
235     int brack_cnt = 0;                        //记录未匹配的左括号个数 
236     ll num, op;
237     for (int i = 1; i < lengt; i++)        //循环生成算式 
238     {
239         if (div)                            //若此时需要生成的数字前的负号是'/',则需要特判此次生成的数字不能为0 
240         {
241             div = false;
242             do{
243                 num = rand()%maxn;
244             }while(num == 0);
245             cout<< num;
246             fout<< num;
247             
248         }
249         else
250         {
251             num= rand()%maxn;
252             fout <<num;
253             cout<<num;
254         }//否则直接生成数字输出 
255         int tmpcnt = brack_cnt;
256         for (int j = 0; j < tmpcnt; j++)    //若当前有未匹配的左括号,则对每一个未匹配的左括号,都有一定概率生成相应右括号。    
257         {
258             if ((rand()%5) > 2)                //生成右括号概率为0.6
259             {
260                 brack_cnt--;
261                 
262                 fout << ")";
263                 cout<<")";
264             }
265         }
266         
267         op = rand()%4;                        //生成运算符 
268         fout << Op[op];
269         cout << Op[op];
270         if (op == 3)                        //若生成了除号,则需要置相应标志位 
271             div = true;
272         
273         if (!(rand()%3))                    //以一定概率生成左括号,概率为1/3 
274         {
275             fout << "(";
276             cout<<"(";
277             brack_cnt++;
278             num= rand()%maxn;//生成左括号后必须生成一个数字和运算符,不然可能出现(15)这样的错误 
279             fout <<num;
280             cout<<num;
281             op = rand()%4;
282             fout << Op[op];
283             cout<<Op[op];
284             if (op == 3)
285                 div = true;
286         }
287     }
288     if (div)                                //生成最后一个数字,该数字后不需要跟运算符 
289     {
290         div = false;
291         do{
292             num = rand()%maxn;
293         }while(num == 0);
294         fout << num;
295         cout<< num;    
296     }
297     else
298     {
299         num=rand()%maxn;
300         fout << num;
301         cout<<num;
302         
303     }
304     while(brack_cnt--)              //补全右括号 
305     {
306         fout << ")";
307         cout << ")";
308     }
309         cout<<"=";
310         fout<< endl;
311         cout<<endl;
312         
313 }
314     bool isNum(char x)            //判断是否是数字
315 {
316     return (x >= '0' && x <= '9');
317 }
318 
319 bool isOp(char x)             //判断是否是操作符
320 {
321     return (x == '+' || x == '-' || x == '*' || x == '/' || x == '(' || x == ')');
322 }
323 
324 int priority(char x)          //返回一个操作符的优先级
325 {
326     if (x == '-' || x == '+')
327         return 1;
328     else if (x == '*' || x == '/')
329         return 2;
330     else if (x == '(')
331         return 0;
332     else
333         return -1;
334 }
335 bool nifix_to_post()
336 {
337     memset(post, 0, sizeof(post));
338     stack<char> s;                                //操作符栈,用来压操作符 
339 /*    ************************************************************************************************
340 #    由于操作数是多位的,所以我们逐位做一个累加暂存的工作,当遇到操作符时,代表此操作符前的数暂存完毕, 
341 #    需要将其入栈,但也不是所有操作符前都有操作数,如'*('等,所以我们需要一个标志位来表示某个操作符前
342 #    是否进行过暂存操作数的处理。 
343 *///************************************************************************************************** 
344     bool havenum = false;                        
345     int tmp = 0, pos = 0;                        //tmp为暂存多位数的变量,pos为后缀数组存储位置 
346     for (int i = 0; nifix[i] != ''; i++)        //循环遍历中缀数组 
347     {
348         if (isNum(nifix[i]))                     //若当前字符是数字,则进行暂存操作。并标识已有操作数 
349         {
350             havenum = true;
351             tmp = tmp*10 + (nifix[i]-'0');
352         }
353         else if (isOp(nifix[i]))                //若当前字符是操作符则进行如下操作 
354         {
355             //中缀表达式合法性判断,判断是否有连续两个字符相连,若有则代表出错 
356             if (isOp(nifix[i-1]) && nifix[i-1] != ')' && nifix[i] != '(') 
357                 return true; 
358             //如果操作符前有操作数,则将得到的操作数输出至后缀表达式 
359             if (havenum)
360             {
361                 havenum = false;
362                 post[pos++] = tmp + '0';
363                 tmp = 0;
364             }
365             //如果操作符为右括号,则按规则进行出栈如后缀表达式等操作 
366             if (nifix[i] == ')')
367             {
368                 if (s.empty())                    //中缀表达式合法性判断,判断括号匹配 
369                     return true;
370                 while(s.top() != '(')
371                 {
372                     post[pos++] = s.top();
373                     s.pop();
374                     if (s.empty())                //中缀表达式合法性判断,判断括号匹配 
375                         return true;
376                 }
377                 s.pop();
378             }
379             else if (nifix[i] == '(')            //如果是左括号则直接入栈 
380                 s.push(nifix[i]);
381             else                                //如果是+-*/则按规则操作 
382             {
383                 while (!s.empty() && priority(nifix[i]) <= priority(s.top()))
384                 {
385                     post[pos++] = s.top();
386                     s.pop();
387                 }
388                 s.push(nifix[i]);
389             }
390         }
391         else                                    //中缀表达式合法性判断,判断是否含非法符号 
392             return true;
393     }
394     //若有操作数,则将其输出至后缀表达式 
395     if (havenum)
396     {
397         havenum = false;
398         post[pos++] = tmp + '0';
399         tmp = 0;
400     }
401     //将栈中操作符一次输出到后缀表达式中 
402     while(!s.empty())
403     {
404         if (s.top() == '(')                        //中缀表达式合法性判断,判断括号匹配 
405             return true;
406         post[pos++] = s.top();
407         s.pop(); 
408     }
409     return false;
410 }
411 ll gcd(ll m, ll n)
412 {
413     ll    tmp;
414     tmp = m % n;
415     while(tmp)
416     {
417         m = n;
418         n = tmp;
419         tmp = m % n;
420     }
421     return n;
422 }
423 bool cal_result()
424 {
425     stack<num> s;                                //用来存放操作数的栈 
426     for (int i = 0; i < (strlen(post)); i++)        //循环遍历后缀表达式 
427     {
428         if (!isOp(post[i]))                        //如果是数字则直接入栈 
429         {
430             num tmp(post[i]-'0', 1);
431             s.push(tmp);
432         }
433         else
434         {
435             //取出两个操作数,如果操作数数量不够,则出错,返回 
436             if (s.empty())
437                 return true;
438             num b = s.top(); s.pop();
439             if (s.empty())
440                 return true;
441             num a = s.top(); s.pop();
442             num c;
443 
444             if (post[i] == '+')                    //操作符是'+',进行上述规则运算 
445             {
446                 c.numerator = a.numerator * b.denominator + b.numerator * a.denominator;
447                 c.denominator = a.denominator * b.denominator;
448             }
449             else if (post[i] == '-')            //操作符是'-',进行上述规则运算
450             {
451                 c.numerator = a.numerator * b.denominator - b.numerator * a.denominator;
452                 c.denominator = a.denominator * b.denominator;
453             }
454             else if (post[i] == '*')            //操作符是'*',进行上述规则运算 
455             {
456                 c.numerator = a.numerator * b.numerator;
457                 c.denominator = a.denominator * b.denominator;
458             }
459             else if (post[i] == '/')            //操作符是'/',进行上述规则运算 
460             {
461                 if (b.numerator == 0)            //如果除的是0,则出现除法错误,返回 
462                     return true;
463                 c.numerator = a.numerator * b.denominator;
464                 c.denominator = a.denominator * b.numerator;
465             }
466             else                                //其他情况则出错 
467                 return true;
468             if (c.numerator != 0)                //若结果不为0,则对分子分母约分 
469             {
470                 ll div = gcd(c.denominator, c.numerator);
471                 c.denominator /= div;
472                 c.numerator /= div;
473             }
474             s.push(c);                            //将约分后结果入栈 
475         }
476     }
477     if (s.size() > 1)                            //如果所有操作符都进行相应操作数后栈内还有多个元素,则说明出错,返回 
478         return true;
479     res = s.top();                                //保存结果 
480     s.pop();
481     if (res.denominator < 0)                    //化简结果,将分母的负号移到分子上 
482     {
483         res.numerator = -res.numerator;
484         res.denominator = -res.denominator;
485     }
486     return false;    
487 }
488 
489 bool trans_ans()
490 {
491     int i = 0;
492     ll tmp = 0;
493     //两个标志位分别标志用户输入的分子分母是否为负数 
494     bool num_flag = false, deno_flag = false;
495     //先判断分子是否为负 
496     if (ans[i] == '-')
497     {
498         num_flag = true;
499         i++;
500     }
501     //接收第一个数字 
502     while(isNum(ans[i]))
503     {
504         tmp = tmp * 10 + (ans[i] - '0');
505         i++;
506     }
507     //若第一个数为负数,则将转化过来的整数取负 
508     if (num_flag)
509         tmp = -tmp;
510     //保存分子 
511     rst.numerator = tmp;
512     //分母赋初值为1 
513     rst.denominator = 1;
514     tmp = 0;
515     //判断是否是分数 
516     if (ans[i] == '/')
517     {
518         //判断分母是否为负数 
519         if (ans[++i] == '-')
520         {
521             deno_flag = true;
522             i++;
523         }
524         //接收第二个数 
525         while(isNum(ans[i]))
526         {
527             tmp = tmp * 10 + (ans[i] - '0');
528             i++;
529         }
530         //若第二个数为负数,则将转化过来的整数取负
531         if (deno_flag)
532             tmp = -tmp;
533         //保存分母 
534         rst.denominator = tmp;
535     }
536     //若分母为0,则用户输入的结果是非法的 
537     if (rst.denominator == 0)
538         return true;
539     //若此时没有遍历所有的字符,则说明输入是非法的 
540     if (i != strlen(ans))
541         return true;
542     //化简分母的负号,将其移至分子 
543     if (rst.denominator < 0)
544     {
545         rst.numerator = -rst.numerator;
546         rst.denominator = -rst.denominator;
547     }
548     //若用户输入的分子分母都是负数,则用户输入不符合规范,我们取分母为0(因为计算结果不可能出现分母为0的状况)标志这种情况的发生 
549     if (num_flag && deno_flag)
550         rst.denominator = 0;
551     return false;
552 }
553 
554 
555 int main()
556 {
557     fraction frac,frac2;
558     int sj1,sj2,sf=1,sj3,sj4,r,j=1;//定义随机数及算符
559     int above,below;
560     int Num;//题的数量
561     int numchose;//运算数选择
562     char sfchose;//算符选择
563     char yschose;//余数选择
564     char jf;//减法结果选择
565     int qznum;//取值范围
566     int ans_2[length];//存放正确的答案
567     int ans_4[length]={0};//存放正确的余数
568     srand((unsigned)time(NULL)); //srand函数是以现在系统时间作为时间种子产生随机数
569     cout<<"*****欢迎使用自动出题系统*****"<<endl;
570     cout<<"请对以下内容进行初始化设置:"<<endl;
571     cout<<"请选择运算数(1.二个运算数 2.多个运算数)"<<endl;
572     cin>>numchose;
573     if(numchose==1)
574     {
575         cout<<"请输入打印题数:"<<endl;
576     cin>>Num;
577     cout<<"请选择是否有乘除法?(y/n)"<<endl;
578     cin>>sfchose;
579     cout<<"请输入一个值确定算式中数值取值范围:"<<endl;
580     cin>>qznum;
581     cout<<"减法结果中出现负数吗?(y/n)";
582     cin>>jf;
583 
584     if(sfchose=='y')
585     {
586         cout<<"请选择除法有无余数?(y/n)"<<endl;
587         cin>>yschose;
588     }
589         cout<<"********************************"<<endl;
590 
591     for(int i=0;i<Num;i++)
592     {
593             sj1=rand()%qznum;
594             sj2=rand()%qznum;
595             sj3=rand()%qznum;
596             sj4=rand()%qznum;
597             if(sfchose=='n')//无乘除法
598             {
599                  sf=rand()%4;         
600             }
601             if(sfchose=='y')//有乘除法
602             {
603                   sf=rand()%8; 
604             }
605             switch(sf)
606                 {        
607                      case 0:
608                        cout<<sj1<<"+"<<sj2<<"=     "<<endl;
609                        ans_2[i]=sj1+sj2;
610                        answer(ans_2,i);
611 
612                      break;
613                     case 1:
614                        if(jf=='n')//无负数
615                        {
616                            if(sj1<sj2)
617                            {
618                               cout<<sj2<<"-"<<sj1<<"=    "<<endl;
619                               ans_2[i]=sj2-sj1;
620                               answer(ans_2,i);
621                         
622                            }
623                            else
624                            {
625                                cout<<sj1<<"-"<<sj2<<"=    "<<endl;
626                                ans_2[i]=sj1-sj2;
627                                answer(ans_2,i);
628                            }
629                         }
630                        else
631                        {
632                             cout<<sj1<<"-"<<sj2<<"=    "<<endl;
633                             ans_2[i]=sj1-sj2;
634                             answer(ans_2,i);
635                         
636                        } 
637                        break;
638                   case 2:
639                        if(sj1>sj3)
640                        {
641                            r=sj1;
642                            sj1=sj3;
643                            sj3=r;
644                        }
645                        if(sj2>sj4)
646                        {
647                            r=sj2;
648                            sj2=sj4;
649                            sj4=r;
650                        }
651                      cout<<"("<<sj1<<"/"<<sj3<<")"<<"+"<<"("<<sj2<<"/"<<sj4<<")=     "<<endl;
652                      frac.setvalue(sj1,sj3);
653                      frac2.setvalue(sj2,sj4);
654                      cout<<"输入分子和分母(用空格隔开,结果化到最简)";
655                      cin>>above>>below;
656                      frac.add(frac2).display(above,below); 
657 
658                     break;
659                   case 3:
660                         if(sj1>sj3)
661                         {
662                             r=sj1;
663                             sj1=sj3;
664                             sj3=r;
665                         }
666                         if(sj2>sj4)
667                         {
668                             r=sj2;
669                             sj2=sj4;
670                             sj4=r;
671                         }
672                         if(jf=='n')//减法结果无负数
673                         {
674                             if((sj1/sj3)<(sj2/sj4))
675                             { 
676                                 cout<<"("<<sj2<<"/"<<sj4<<")"<<"-"<<"("<<sj1<<"/"<<sj3<<")=     "<<endl;
677                                 frac.setvalue(sj2,sj4);
678                                 frac2.setvalue(sj1,sj3);
679                                 cout<<"输入分子和分母(用空格隔开,结果化到最简)";
680                                 cin>>above>>below;
681                                 frac.sub(frac2).display(above,below); 
682 
683                             }
684                             else
685                             {
686                                 cout<<"("<<sj1<<"/"<<sj3<<")"<<"-"<<"("<<sj2<<"/"<<sj4<<")=     "<<endl;
687                                 frac.setvalue(sj1,sj3);
688                                 frac2.setvalue(sj2,sj4);
689                                 cout<<"输入分子和分母(用空格隔开,结果化到最简)";
690                                 cin>>above>>below;
691                                 frac.sub(frac2).display(above,below); 
692                             }
693                         }
694                          else
695                          {
696                                 cout<<"("<<sj1<<"/"<<sj3<<")"<<"-"<<"("<<sj2<<"/"<<sj4<<")=     "<<endl;
697                                 frac.setvalue(sj1,sj3);
698                                 frac2.setvalue(sj2,sj4);
699                                 cout<<"输入分子和分母(用空格隔开,结果化到最简)";
700                                 cin>>above>>below;
701                                 frac.sub(frac2).display(above,below); 
702                          }
703                        break;
704                    case 4:
705                       cout<<sj1<<"*"<<sj2<<"="<<endl;
706                       ans_2[i]=sj1*sj2;
707                       answer(ans_2,i);
708                     break;
709                    case 5:
710                        if(sj2==0)//分母为零则不计入总数
711                        {
712                            i=i-1;
713                         
714                        }
715                        else if(yschose=='n')//除法没有余数
716                        {
717                            if(sj1%sj2==0)
718                            {
719                                cout<<sj1<<"/"<<sj2<<"="<<endl;
720                                ans_2[i]=sj1/sj2;
721                                answer(ans_2,i);
722 
723                         
724                            }
725                            else 
726                            {
727                                i=i-1;
728                              
729                            }
730                        }
731                        else if(yschose=='y')//除法有余数
732                        {
733                              if(sj1%sj2!=0)
734                            {
735                                cout<<sj1<<"/"<<sj2<<"="<<endl;
736                                ans_2[i]=sj1/sj2;
737                                ans_4[i]=sj1-sj2*ans_2[i];
738                                answer_1(ans_2,i,ans_4);
739                     
740                            }
741                            else 
742                            {
743                                i=i-1;
744                         
745                            }
746 
747                        }
748                        break;
749                    case 6:
750                     if(sj1>sj3)
751                     {
752                         r=sj1;
753                         sj1=sj3;
754                         sj3=r;
755                     }
756                     if(sj2>sj4)
757                     {
758                         r=sj2;
759                         sj2=sj4;
760                         sj4=r;
761                     }
762                      cout<<"("<<sj1<<"/"<<sj3<<")"<<"*"<<"("<<sj2<<"/"<<sj4<<")=     "<<endl;
763                      frac.setvalue(sj1,sj3);
764                      frac2.setvalue(sj2,sj4);
765                      cout<<"输入分子和分母(用空格隔开,结果化到最简)";
766                      cin>>above>>below;
767                      frac.mul(frac2).display(above,below); 
768                        break;
769                    case 7:
770                        if(sj1>sj3)
771                        {
772                            r=sj1;
773                            sj1=sj3;
774                            sj3=r;
775                        }
776                      if(sj2>sj4)
777                      {
778                         r=sj2;
779                         sj2=sj4;
780                         sj4=r;
781                      }
782                        cout<<"("<<sj1<<"/"<<sj3<<")"<<"/"<<"("<<sj2<<"/"<<sj4<<")=     "<<endl;
783                        frac.setvalue(sj1,sj3);
784                        frac2.setvalue(sj2,sj4);
785                        cout<<"输入分子和分母(用空格隔开,结果化到最简)";
786                        cin>>above>>below;
787                        frac.div(frac2).display(above,below); 
788                        break;
789                    default:
790                    break;
791                 }
792     }
793      cout<<"共做对  "<<rights<<"  道题"<<endl;
794      cout<<"共做错  "<<wrong<<"  道题"<<endl;
795     }
796     else
797     {
798         
799         cout<<"请输入出题数目:";
800         cin >>Num ;
801         cout<<"请输入一个值确定算式中数值取值范围:"<<endl;
802         cin>>qznum;
803         cout<<"******************************************"<<endl;
804         while(Num--)
805         {
806             create(qznum);
807         }
808         //计数器请0 
809     cnt_right = cnt_wrong = 0;
810     ifstream infile;
811     infile.open("equation.txt", ios::in);
812       if(infile.is_open() == false)
813       {
814          cerr << "open error!" << endl;
815          exit(1);
816       }
817         
818     while( infile >> nifix)
819     {
820         error = nifix_to_post();            //中缀转后缀,并接受错误信息 
821         if (error)                            //若过程出错,则输出错误信息 
822         { 
823             cout << "读取式子出错!" << endl;
824             return 0; 
825         }
826         
827         //test_post();
828         
829         error = cal_result();                //后缀表达式计算,并接受错误信息 
830         if (error)                            //若过程出错,则输出错误信息
831         { 
832             cout << "计算中出错..." << endl;
833             return 0; 
834         }
835         
836         cout << "请输入答案: ";
837         cin >> ans;                            //接受用户答案 
838         error = trans_ans();                //答案翻译, 并接受错误信息
839         if (error)                            //若过程出错,则输出错误信息
840         { 
841             cout << "输入不合法答案!" << endl;
842             return 0; 
843         }
844         //若用户输入和城西计算答案的分子分母相等或分子均为0,则说明用户输入答案正确 
845         if ((rst.denominator == res.denominator && rst.numerator == res.numerator) || (rst.numerator == res.numerator && rst.numerator == 0))
846         {
847             cnt_right++;
848             cout << "正确!" << endl;
849         }
850         //否则答案错误,程序输出正确答案 
851         else
852         {
853             cnt_wrong++;
854             cout << "错误. 答案是 ";
855             if (res.denominator == 1)
856                 cout << res.numerator << "." << endl;
857             else
858                 cout << res.numerator << "/" << res.denominator << "." << endl;
859         }
860     }
861     cout << "统计结果..." << endl;
862     //输出统计结果 
863     cout << "你答了" << cnt_right+cnt_wrong << " 道题 ";
864     cout << "正确数:" << cnt_right << "   错误数: " << cnt_wrong << "" << endl;
865     infile.close();
866  
867     }
868       
869      return 0;
870 }

四、运行截图

五、项目计划日志

日期&&任务 听课 编写程序 阅读相关书籍 网上查找资料   日总计
周一 100   30 20 150
周二   120 30 30 180
周三   30 30 10 70
周四 100 20  30   150
周五   120   30 30 180
周六   45 30 10 85
周日     30  20 50
周总计 200 335 210 120

865

 

时间记录日志

3/14

日期 开始时间 结束时间 中断时间 净时间 活动 备注
3/14 14:00 15:50 10 100 听课 软件工程上课
  21:00 21:  30   30 阅读书籍 《构建之法》
  22:10 22: 30   20 网上查找资料  
3/15 21:00 21:30 20 120 编写程序 结对开发-四则运算3
  22:  15 22:  25   30 网上查找资料  
   22:30  23:00    30  阅读书籍  《构建之法》
3/16 19:  24 20: 00  6 30 编写程序 结对开发-四则运算3
  22:00 22: 30   30 阅读书籍 《构建之法》
  22:40 22: 50   10 查找资料  
3/17 14:00 15:  50   100 上课 软件工程上课
  18:00 18: 20   20 编写程序 结对开发-四则运算3
   22:00  22:30    30  阅读书籍  《构建之法》
3/18 14:  00 16:  20  20 120  编写程序 结对开发-四则运算3
  11:23 12: 00 7 30 网上查找资料  
   21:00  21:30    30  阅读书籍 《构建之法》
3/19 9: 00   9: 30 50 30 阅读书籍 《构建之法》
  10: 00 11: 00 15 45 编写程序 结对开发-四则运算3
  9:  45   9: 55   10 网上查找资料  
3/20 9:00 9: 30  23 30 阅读书籍 《构建之法》
  14:50 15: 10   20 网上查找资料   

 

缺陷记录日志

日期 编号 类型 引入阶段 排除阶段 修复时间 备注
3/18 1 20 编码 编译 5 文件关闭出现错误
3/18 2 20 编码 编译 1 变量未初始化
3/18 20  编码  编译  定义了相同名字的变量 

同组伙伴博客:http://www.cnblogs.com/qizhonh/

工作照:

原文地址:https://www.cnblogs.com/a1397240667/p/5294473.html