个人作业1——四则运算题目生成程序(基于控制台)
码市链接: https://coding.net/u/Lynn_LinYan/p/Random/git
一、需求分析:
- 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 = 7/24
- 运算符为 +, −, ×, ÷
- 并且要求能处理用户的输入,并判断对错,打分统计正确率。
- 要求能处理用户输入的真分数, 如 1/2, 5/12 等
- 使用 -n 参数控制生成题目的个数,例如执行下面命令将生成10个题目
Myapp.exe -n 10
- 基本功能:实现简单的加减乘除出题并验证对错
- 扩展功能:能实现真分数的加减乘除
- 高级功能:统计正确率和错误率
![](https://images2015.cnblogs.com/blog/1110659/201703/1110659-20170306132555516-239484236.png)
项目中设计了一个重要的类,其方法和属性如上图所示;还有一个就是main类,主要实现输入输出以及验证答案是否正确。在实现的过程中主要就是分数的运算比较难,设计产生随机数的话,其实将整数看成分母为1的分数比较好处理,这样一来,问题就转换成分数的加减乘除了,但是分数的运算涉及到最大公约数和最小公倍数,所以写函数的时候也写了这两个函数来处理分数的加减以及最后结果的化简。最后通过重写toString方法输出真确的答案,在main函数中与用户输入的答案进行一一比较,判断正确并统计正确率。
1.重要的函数:
产生随机数:
1 //随机产生一个分数或者整数 2 public void createFenShu(RandomNum f){ 3 Random random=new Random(); 4 int a=random.nextInt(101); 5 int b=random.nextInt(100) + 1; //产生随机数1-100作为分母 6 if(b!=0&&((a%b==0)||a<b)) //为整数或者真分数(分母不为0且分子小于分母) 7 { 8 f.setFenzi(a); 9 f.setFenmu(b); 10 } 11 else 12 createFenShu(f); 13 } 14 public void createInteger(RandomNum f){ 15 Random random=new Random(); 16 int a=random.nextInt(101); 17 f.setFenzi(a); 18 f.setFenmu(1); //分母为1,即产生整数 19 }
1 @Override 2 public String toString() { 3 // TODO Auto-generated method stub 4 int n = this.FindZuiDa(); 5 int fenzi = this.fenzi/n; 6 int fenmu = this.fenmu/n; 7 if(fenzi == 0){ 8 return Integer.toString(fenzi); 9 } 10 if(fenzi >= fenmu){ //如果分子大于分母 11 if(fenzi % fenmu == 0){ 12 return Integer.toString(fenzi / fenmu); 13 }else{ 14 return Integer.toString(fenzi) + "/" + Integer.toString(fenmu); 15 } 16 }else{ 17 return Integer.toString(fenzi) + "/" + Integer.toString(fenmu); 18 } 19 } 20
加法运算:
1 //加运算 2 public String Add(RandomNum r2){ 3 int zuiXiao =this.FindZuixiao(r2); 4 int fenzi = ((zuiXiao / this.fenmu) * this.fenzi) + ((zuiXiao / r2.getFenmu())* r2.getFenzi()); 5 this.setFenzi(fenzi); 6 this.setFenmu(zuiXiao); 7 return this.toString(); 8 }
减法运算:
1 //减运算 2 public String Substract(RandomNum r2){ 3 int zuiXiao =this.FindZuixiao(r2); 4 int fenzi = ((zuiXiao / this.fenmu) * this.fenzi) - ((zuiXiao / r2.getFenmu())* r2.getFenzi()); 5 this.setFenzi(fenzi); 6 this.setFenmu(zuiXiao); 7 return this.toString(); 8 }
乘法运算:
1 public String mul(RandomNum r2){ 2 this.fenzi = this.fenzi * r2.getFenzi(); 3 this.fenmu = this.fenmu * r2.getFenmu(); 4 return this.toString(); 5 }
除法运算:
1 //除运算 2 public String deivde(RandomNum r2){ 3 this.fenzi = this.fenzi * r2.getFenmu(); 4 this.fenmu = this.fenmu * r2.getFenzi(); 5 return this.toString(); 6 }
2.代码说明:
1 int totalCnt = 0; //总题数 2 int cnt = 0; //当前已完成的题数,用来做循环的判断 3 int rightCnt = 0; //做正确的题数 4 int errorCnt = 0; //做错误的题数 5 Scanner input = new Scanner(System.in); 6 System.out.print("请输入你要做的题数:"); 7 totalCnt = input.nextInt(); 8 while (cnt < totalCnt) { 9 RandomNum a = new RandomNum(); 10 RandomNum b = new RandomNum(); 11 int number = new Random().nextInt(2); 12 switch (number) { //随机生成的题目是整式或者分式或者混合式子 13 case 0: 14 a.createInteger(a); 15 b.createInteger(b); 16 break; 17 case 1: 18 a.createFenShu(a); 19 b.createFenShu(b); 20 break; 21 default: 22 a.createInteger(a); 23 b.createFenShu(b); 24 break; 25 } 26
(2)用一个随机数产生加减乘除算式中的任意一个并验证用户输入的答案是否与正确答案一致,将分子、分母分别放在StrArr[0],Str[1]中。(注意下面第二张代码展示了如何避免减法产生负数;减法,乘法,除法和加法类似,在此处不一一粘贴代码)
1 number = new Random().nextInt(4); 2 String result ; 3 String[] strArr = new String[2]; //存放用户输入的答案的分子和分母 4 switch (number) { 5 // 加法 6 case 0: 7 System.out.print(a.toString() + " + " + b.toString() + " = "); 8 result = input.nextLine(); 9 while(result.length() == 0 ||result.equals('\n') || result.equals('\r')){ 10 result = input.nextLine(); 11 } 12 if (result.trim().indexOf("/") >= 0) { //如果输入的答案是分数 13 strArr = result.trim().split("/"); //将输入答案的分子分母分开放在strArr[0]和strArr[1]中并去掉空格 14 } else { 15 strArr[0] = result.trim(); 16 strArr[1] = "1"; //否则置分母为1 17 } 18 if (strArr[1].equals("0")) { //若输入的分数分母为0,则答案错误 19 System.out.println("答案错误!正确答案为:" + a.Add(b)); 20 errorCnt++; 21 } else { 22 try { 23 int fz1 = Integer.parseInt(strArr[0].trim()); 24 int fm1 = Integer.parseInt(strArr[1].trim()); 25 RandomNum c = new RandomNum(fz1, fm1); 26 a.Add(b); 27 if (c.toString().equals(a.toString())) { 28 rightCnt++; 29 System.out.println("答案正确!"); 30 } else { 31 errorCnt++; 32 System.out.println("答案错误!正确答案为:" + a.toString()); 33 } 34 } catch (NumberFormatException e) { 35 // TODO Auto-generated catch block 36 //e.printStackTrace(); 37 errorCnt++; 38 System.out.println("答案错误!正确答案为:" + a.Add(b)); 39 } 40 41 } 42 break;
1 // 减法 2 case 1: 3 double x = (double) a.getFenzi() / a.getFenmu(); 4 double y = (double) b.getFenzi() / b.getFenmu(); 5 if (x < y) { //若出现负数,则将减数和被减数替换位置 6 int fzTemp = a.getFenzi(); 7 int fmTemp = a.getFenmu(); 8 a.setFenmu(b.getFenmu()); 9 a.setFenzi(b.getFenzi()); 10 b.setFenmu(fmTemp); 11 b.setFenzi(fzTemp); 12 }
(3)统计正确题数、错误题数以及正确率和错误率
1 System.out.println('\n'+"共答题"+cnt+"道,错误"+errorCnt+"题"+",正确"+rightCnt+"题"); 2 System.out.println("正确率为:"+rightCnt*100/cnt+"%");
3.测试运行
![](https://images2015.cnblogs.com/blog/1110659/201703/1110659-20170306210035516-2115415185.png)
四、展示PSP:这份PSP可能有点不太准,因为当时自己开始做这个实验的时候没有这样的打算,做完后也只能大概一下把零零散散的时间凑起来然后填好这个表格,我觉得花比较多的时间是在考虑如何处理分数这一块,还有整个封装,因为对java没有很好的掌握,很多类合在一起写,不是很规范;再有就是花在测试和改错的时间比较长。我在下面表格中写编写代码的时间比较久是因为挺久没写java的了,很多语句和用法都有些忘记了,然后查找的时间花了挺多。
五、小结
终于来到小结这个天地了,此时此刻我的心情多么欢快啊!!!终于写好了这个作业,其实在写代码的时候遇到了蛮多问题的,一般是先自己百度然后不会的再问同学的。比如在算式出来但是用户自己不小心按回车的情况下,这样也算错误的话,那不是贼可怜,所以想要判断在输入时回车的情况下继续输入,这就得想如何能知道用户输入的是回车呢?刚开始我只是很简单地认为接收到的是换行然后就刷刷刷往里写,但是测试好像通不过,为了这个问题百度了挺久的,最后才找到解决的办法。刚开始做的时候,思路是完全乱的,因为有分数,不太懂怎么处理,各种在网上找灵感,最终通过别人的指点,确定了用分数表示整数。如果很久没写代码,真的会忘记很多,希望自己以后能坚持。这过程真的曲折,但是认真过后最开心了。