一、题目
按用户编写若干道2年级四则运算题
1题目避免重复
2可定制(数量/打印方式)
3可以控制下列参数:是否有乘除法、是否有括号、数值范围、加减有无负数、除法有无余数、是否支持分数(真分数,假分数,…)、是否支持小数(精确到多少位)、打印中每行的间隔可调整。
二、设计思想
上次的设计思想是先生成三个随机数,两个数是操作数,第三个控制乘除加减的选择。
这次同样是生成几个随机数,但需要设置一些判断条件,来满足用户出题要求,写一个出题函数,根据用户要求改变其中的变量,循环调用这个函数出题。
一、题目避免重复
因为随机函数是伪随机,只是一个函数,所以只需保证不与上次出的题相同即可。
方法一、把前面生成的题目存到三个数组,以后依次比较。
方法二、控制选择随机产生的第几个数(如前30,再30个等),或控制srand函数的值,是之每次都不同,即可保证随机产生的数不同。
二、可定制(数量/打印方式)
循环变量由用户输入,确定数量,打印方式由变量控制,由用户输入,操作数数量有用户输入(在选择有无括号)
三、可以控制下列参数:是否有乘除法、是否有括号、数值范围、加减有无负数、除法有无余数、是否支持分数(真分数,假分数,…)、是否支持小数(精确到多少位)、打印中每行的间隔可调整。
所有参数一个数组,统一设置内容,每次都由用户输入来设置,然后根据数组的值设置调用的出题函数的参数,来出题。
乘除只需在加减乘除上加两个运算即可。
括号必须是有三个及以上操作数才能有,否则报错,可固定在第二个操作数前和最后面加括号。
数值范围可以用改变随机数,用1+(int)(范围最大值*rand()/(RAND_MAX+1.0))来改变。
加减有无负数可用随机在操作数前加负号。
除法有无余数可以当随机到除号时对出号第二个操作数循环减一知道成为第一个操作数的除数。
是否支持分数可以把两个操作数通过分号合成一个操作数。
是否支持小数精确到多少位可以改变1+(int)(范围最大值*rand()/(RAND_MAX+1.0))使之除以小数位数乘10即可。
打印中每行间隔可以单独设一个输出来输出间隔。
三、源代码
#include<iostream.h> #include<time.h> #include<stdlib.h> #include<math.h> int main() { int num1,num2,num0,c; int limit[8]; double num3,num4; srand((int)time(0)); // 不同的时间,产生不同的随机数,但不保证缩小范围后是不是一样的数,是缺陷 cout<<"输入题目的数量:"; cin>>num0; cout<<endl; cout<<"输入打印中每行的间隔:"; cin>>limit[0]; cout<<endl; cout<<"输入打印中每行的题目数:"; cin>>limit[1]; //每次都输入太麻烦了,这个设置一般是一样的,可否改为设置一次即可 cout<<endl; cout<<"输入操作数的数值范围的最小值和最大值:"; cin>>limit[2]>>limit[3]; cout<<endl; cout<<"是否有乘除法,有输入1,没有输入0:"; cin>>limit[4]; cout<<endl; cout<<"加减有无负数,有输入1,没有输入0:"; cin>>limit[5]; cout<<endl; if(limit[4]==1) { cout<<"除法有无余数,有输入1,没有输入0:"; cin>>limit[6]; cout<<endl; } if(limit[4]==0) { cout<<"是否支持小数,有输入1,没有输入0:"; cin>>limit[7]; cout<<endl; if(limit[7]==1) { cout<<"若支持小数,精确到多少位:"; cin>>limit[8]; cout<<endl; } } for(int i=0;i<num0;i++) //输出题目的循环 { num1=limit[2]+(int)(limit[3]*rand()/(RAND_MAX+1.0)); num2=limit[2]+(int)(limit[3]*rand()/(RAND_MAX+1.0)); c=1+(int)(4*rand()/(RAND_MAX+1.0)); if(limit[4]==1) { if(c%4==0) { if(limit[6]==1) { if(num1%num2==0) cout<<"第"<<i+1<<"道:"<<num1<<"/"<<num2<<"="<<" "; else { while(num1%num2!=0) { num2=num2-num1%num2; } cout<<"第"<<i+1<<"道:"<<num1<<"/"<<num2<<"="<<" "; } } } //输出有无余数的除法 if(c%4==1) cout<<"第"<<i+1<<"道:"<<num1<<"+"<<num2<<"="<<" "; if(c%4==2) cout<<"第"<<i+1<<"道:"<<num1<<"-"<<num2<<"="<<" "; if(c%4==3) cout<<"第"<<i+1<<"道:"<<num1<<"*"<<num2<<"="<<" "; } //输出有乘除法的题目 else { if(limit[7]==1) { num3=pow(0.1,limit[8])+(int)(0.1*rand()/(RAND_MAX+1.0))+num1; num4=pow(0.1,limit[8])+(int)(0.1*rand()/(RAND_MAX+1.0))+num2; } if(limit[5]==1) { if(c%2==0) cout<<"第"<<i+1<<"道:"<<pow(-1,i)*num3<<"-"<<pow(-1,i+1)*num4<<"="<<" "; if(c%2==1) cout<<"第"<<i+1<<"道:"<<pow(-1,i)*num3<<"+"<<pow(-1,i+1)*num4<<"="<<" "; } else { if(c%2==0) cout<<"第"<<i+1<<"道:"<<num3<<"-"<<num4<<"="<<" "; if(c%2==1) cout<<"第"<<i+1<<"道:"<<num3<<"+"<<num4<<"="<<" "; } //输出有无负数的加减 } if((i%limit[1])+1==limit[1]) //每行打印的题目数 for(int k=0;k<=limit[0];k++) cout<<endl; //每行打印的间隔 } return 0; }
四、实验截图
五、实验总结
经过漫长的努力,终于完成了大部分要求,我基础不大好,这次真的是费了很大劲。。。。
编写时自己没有用类啊,函数啊什么的,全部语句都堆在了主函数里,以后要改正。
如何确保没有重复的题目和如何选择有无括号这两项我没完成,不会弄。。。但时间来不及了,以后问问同学,掌握这两项。
六、psp
一、项目计划总结:
周活动总结表
姓名:李海超 日期:2015年3月15日
日期 任务 |
听课 |
编写程序 |
阅读课本 |
准备考试 |
日总计 |
||
周日 |
|||||||
周一 |
|||||||
周二 |
100 |
30 |
130 |
||||
周三 |
60 |
10 |
70 |
||||
周四 |
60 |
10 |
70 |
||||
周五 |
100 |
60 |
10 |
70 |
|||
周六 |
60 |
10 |
70 |
||||
周总结 |
410 |
阶段时间和效率 周数(上一次周活动表的周数+1):
不包括上一周在内的累计时间
总计 |
|||||||
平均 |
|||||||
最大 |
|||||||
最小 |
以前各周的累计时间
总计 |
|||||||
平均 |
|||||||
最大 |
|||||||
最小 |
二、时间记录表:
学生 李海超 日期 2015/3/15
教师 王建民 课程 PSP
日期 |
开始时间 |
结束时间 |
中断时间 |
净时间 |
活动 |
备注 |
3.11 |
12:30 |
1:10 |
70 |
编程看书 |
||
3.12 |
12:30 |
1:10 |
70 |
编程看书 |
||
3.13 |
12:30 |
1:10 |
70 |
编程看书 |
||
3.14 |
12:30 |
1:10 |
70 |
编程看书 |
||
三、缺陷记录日志:
学生 李海超
日期 2015/3/15
教员 王建民
程序号 2
日期 |
编号 |
类型 |
引入阶段 |
排除阶段 |
修复时间 |
修复缺陷 |
3.11 |
||||||
无,但不会使题目不重复,决定跳过这一步 |
||||||
3.12 |
||||||
If中比较时应用==而不是= |
||||||
3.13 |
||||||
应注意if else格式,用{}包起下面的语句,否则会不清晰 |
||||||
3.14 |
||||||
注意变量类型,是需要double转变成int还是反之。 |