用C++实现的随机生成300道四则运算练习题的程序

发布时间 2023-04-12 22:17:52作者: 極限

一、前言

本次专业课实验为结对编程,即一个同学coding,另一个同学在旁边审核代码,经过一定时间后再交换角色。队友学号为2152202。

 

二、题设

小学老师要每周给同学出300道四则运算练习题。这个程序有很多种实现方式:C/C++/C#/VB.net/Java/Excel/Unix Shell/Emacs/Powershell/Vbscript/Perl/Python。

具体要求:

1.一或两个运算符(a+b或a+b+c),100 以内的数字,不需要写答案。

2.需要检查答案是否正确,并且保证答案在 0..100 之间。

3.尽可能地多设置一些条件。

 

三、分析

经讨论后,我们结对小组选择了相对比较熟悉的C++语言。由于是为小学生开发的四则运算练习题,考虑到小学生对于分数运算可能相对不太熟悉,于是除法算法需要对运算结果进行判断。具体判断方式为,如果运算结果是分数,那么这题废弃,重新出题。加减乘法不需要考虑分数运算问题,但存在运算结果在0-100范围外的情况,若经过判断,运算结果在0-100在范围之外,那么该题废弃,重新出题。通过rand() % 3+ 1生成1-4的随机数用于实现加减乘除运算符号的随机。

在筛选有效题目的基础上,我们再使用if语句对做题人输入答案的正确性进行验证,并输出相应的提示性语句。最后计算做题人本次答题的正确率并输出。此外我们还增加了将错题写入文件的功能,文件下保留了使用此程序答题的历史所有错题。

为实现随机出题,我们使用了ctime头文件。

 

 

四、实验环境

Dev-C++  Win 10

 

五、代码及运行结果

 

  1 #include <iomanip>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<ctime>
  5 #include<fstream>
  6 using namespace std;
  7 
  8 int main()
  9 {
 10     clock_t t0,t1;  //用于计算运行时间
 11     int sum,num=-1,flag=1,f_right=0;        //sum用来存放正确的结果,num用来存放答题者输入的结果,flag用来记录有效题目数量 ,f_right用来记录正确数量 
 12     double accuracy=0;        //正确率 
 13     for(t0 = clock();flag<=300;){
 14         srand(time(NULL));
 15         int a,b;        //生成两个随机数
 16         a= rand() %100;
 17         b= rand() %100;
 18         int e= rand() % 3+ 1;        //判断四则运算符号 生成0+1~3+1的随机数
 19         if(e==1){            //加法 
 20             sum=a+b;
 21             if(sum<=100){
 22                 cout<<""<<flag<<"题:" ;
 23                 cout<<a<<"+"<<b<<"=";
 24                 cin>>num;
 25                 flag++;
 26             }
 27         }
 28     
 29         else if(e==2){        //减法 
 30             sum=a-b;
 31             if(sum<=100&&sum>=0){
 32                 cout<<""<<flag<<"题:" ;
 33                 cout<<a<<"-"<<b<<"=";
 34                 cin>>num;
 35                 flag++;
 36             }
 37         }
 38     
 39         else if(e==3){        //乘法 
 40             sum=a*b;
 41             if(sum<=100&&sum>=0){
 42                 cout<<""<<flag<<"题:" ;
 43                 cout<<a<<"*"<<b<<"=";
 44                 cin>>num;
 45                 flag++;
 46             }
 47         }
 48     
 49         else if(e==4){        //除法 
 50             if(b!=0&&a%b==0){
 51                 sum=a/b;
 52                 if(sum<=100&&sum>=0){
 53                     cout<<""<<flag<<"题:" ;
 54                     cout<<a<<"/"<<b<<"=";
 55                     cin>>num;    
 56                     flag++;
 57                 }
 58             }
 59         }
 60         
 61         if(num==sum){
 62             cout<<"恭喜你答对了!"<<endl;
 63             system("pause");
 64             f_right++;
 65             num=-1;
 66         }
 67         else if(num!=-1){        //&&num!=sum
 68             cout<<"很遗憾你答错了!"<<endl;    
 69             
 70             ofstream ofs;
 71             ofs.open("file.txt", ios::app);
 72 
 73             if(e==1){
 74                 ofs<<a<<"+"<<b<<"="<<sum<<endl<<"你的答案:"<<num<<endl;    
 75             }
 76             else if(e==2){
 77                 ofs<<a<<"-"<<b<<"="<<sum<<endl<<"你的答案:"<<num<<endl;    
 78             }
 79             else if(e==3){
 80                 ofs<<a<<"*"<<b<<"="<<sum<<endl<<"你的答案:"<<num<<endl;    
 81             }
 82             else if(e==4){
 83                 ofs<<a<<"/"<<b<<"="<<sum<<endl<<"你的答案:"<<num<<endl;    
 84             }
 85 
 86             
 87             ofs.close();
 88             
 89             system("pause");
 90             num=-1;
 91         }
 92         if((flag-1)%10==0)
 93         system("cls");
 94 
 95     }
 96     t1 = clock();
 97     int time=(int)(t1-t0)/CLOCKS_PER_SEC;
 98     flag=flag-1;
 99     accuracy=(double)f_right/(double)flag;
100 //    cout<<"恭喜做完本轮试题,您本次的正确率为:"<<accuracy*100<<"%";
101     cout<<"恭喜做完本轮试题,您本次的正确率为:"<<fixed<<setprecision(2)<<accuracy*100<<"%"<<"本次作答总用时为:"<<time<<""<<endl; 
102     return 0;
103 }
104 

每十题清一次屏:

显示正确率以及总用时:

 

 

错题记录:

 

 

 

六、遇到的问题及解决方式

1.重复打印

在编码过程中遇到了输出错误后,重复打印了多行输出语句。为解决此问题,我们选择在if语句判断运算结果正确与否过后将num置为-1,避免程序在筛除无效题目后重复打印之前的输出语句。

 

2.控制double的小数点位数

由于我们程序中具有计算正确率的功能,于是使用了double类型来存储相关变量。随着正确率分子分母的变化,在输出时小数点后的位数也有所变化。为了方便老师等相关人员统计做题情况,我们查询资料后使用了iomanip头文件,利用setprecision函数来控制小数点位数。

相关代码片段:

 

#include <iomanip>

accuracy=(double)f_right/(double)flag;
cout<<"恭喜做完本轮试题,您本次的正确率为:"<<accuracy*100<<"%";

 

 

 

 

 

 

 

 

3.控制随机性

在实际测试中我们发现,如果做题人做题速度过快,那么随着系统时间随机的逻辑则会影响随机性,即在相对短的时间内会出同样的题目,这无疑违背了同学们做题的初衷。于是我们想到利用system("pause"),以此达到延缓出题时间的效果,进一步控制程序的随机性。

改进前:

 

改进后:

 

 

4.显示时间

我们原本的构思是一定时间内当前题未能答出,则自动视为答错了,进入下一题。但实际上实现起来过于复杂,于是经过查阅资料,修改成了显示总时长。

相关代码片段:

 

1 #include<ctime>
2 
3 clock_t t0,t1;  //用于计算运行时间
4 t1 = clock();
5 int time=(int)(t1-t0)/CLOCKS_PER_SEC;
6 cout<<"本次作答总用时为:"<<time<<""<<endl;

 

 

 

 

七、收获与总结

经过本次结对编程实验,我们对结对编程有了更深切的体会。一是感觉结对编程效率比较高,在编程的过程中双方就能实时交流,能及时提出建议或是改正错误,并且由于随时准备交流,所以专注度高。二是结对编程能实现相对更完整的程序。三是结对编程有助于双方能力的提升。总的来说,本次结对编程实验收获颇丰!博主能力有限,如有建议及指正欢迎在评论区提出!