coding.net 网站地址
https://coding.net/u/zachary0320/p/java_test1_git/git
题目描述:
从《构建之法》第一章的 “程序” 例子出发,像阿超那样,花二十分钟写一个能自动生成小学四则运算题目的命令行 “软件”,满足以下需求:
- 除了整数以外,还要支持真分数的四则运算,真分数的运算,例如:1/6 + 1/8 = 7/24
- 运算符为 +, −, ×, ÷
- 并且要求能处理用户的输入,并判断对错,打分统计正确率。
- 要求能处理用户输入的真分数, 如 1/2, 5/12 等
- 使用 -n 参数控制生成题目的个数,例如执行下面命令将生成10个题目
Myapp.exe -n 10
对题目要求的分析:
- 由于是小学四则运算,所以我只是将简单的整数作为运算数,没有小数参加运算;
- 题目在每次开始前会要求输入每次练习的题目数量,然后一次性的打印出所有题目;
- 输出了正确率和错误率;
- 暂时只支持两个运算数;
- 可以判读用户输入的分数是否正确;
- 不支持小数,小数都用分数表示;
PSP:
PSP2.1 | Personal Software Process Stages | Time (%) | Real Time (%) |
Planning | 计划 | 6 | 8 |
· Estimate | 估计这个任务需要多少时间 | 4 | 2 |
Development | 开发 | 0 | 0 |
· Analysis | 需求分析 (包括学习新技术) | 10 | 14 |
· Design Spec | 生成设计文档 | 0 | 0 |
· Design Review | 设计复审 | 0 | 0 |
· Coding Standard | 代码规范 | 2 | 3 |
· Design | 具体设计 | 20 | 7 |
· Coding | 具体编码 | 40 | 44 |
· Code Review | 代码复审 | 0 | 0 |
· Test | 测试(自我测试,修改代码,提交修改) | 10 | 16 |
Reporting | 报告 | 3 | 6 |
· | 测试报告 | 0 | 0 |
· | 计算工作量 | 2 | 4 |
· | 并提出过程改进计划 | 5 | 6 |
在设计代码时没有详细的计划,中途修改的时间比较多。用java编写时,遗忘了很多知识点,边写边想。
程序:
//Generate.java
package test1; import test1.Operate; import java.text.DecimalFormat; import java.util.*; public class Generate { public static void main(String[] args) { // TODO Auto-generated method stub start(); while (!loop()) { start(); } } private static boolean loop() { ... return false; } private static void start() { ... }
//这里是生成函数的方法Generate() private static void generate(String[] titles ,String[] answers) { // TODO Auto-generated method stub for (int i = 0; i < titles.length; i++) { //产生n道题目 String operator = operatorGenerate(i); int x = Number(20); int y = Number(20)+1; titles[i] = x+" "+operator+" "+y+" = "; if (operator == "+") answers[i] = ""+Operate.plus(x,y); if (operator == "-") answers[i] = ""+Operate.subtract(x, y); if (operator == "*") answers[i] = ""+Operate.multiply(x, y); if (operator == "/") { int[] m ={x,1}; int[] n ={y,1}; int[] z = Operate.divide(m, n); if (z[0]==0) { answers[i] = "0"; } else { answers[i] = z[0]+"/"+z[1]; } } } } //随机产生运算数 private static int Number(int num) { // TODO Auto-generated method stub return (int)(Math.random()*num); } //产生返回运算符 private static String operatorGenerate(int num) { // TODO Auto-generated method stub int n = num%4; if(n == 0) return "+"; if(n == 1) return "-"; if(n == 2) return "*"; if(n == 3) return "/"; return null; }
//打印字符串 private static void print(String str) { // TODO Auto-generated method stub System.out.println(str); } }
//分数的生成和运算函数
//与Generate()类似的函数
private static void fenshu(String[] titles, String[] answers) { // TODO Auto-generated method stub for (int i = 0; i < titles.length; i++) { //产生n道题目 String operator = operatorGenerate(i); int[] x = FenShu_function.create(); int[] y = FenShu_function.create(); titles[i] ="("+ x[0]+"/"+x[1]+")"+operator+"("+y[0]+"/"+y[1]+") = "; if (operator == "+") { int[] result = FenShu_function.plus(x, y); answers[i] = result[0]+"/"+result[1]; } if (operator == "-") { int[] result = FenShu_function.subtract(x, y); answers[i] = result[0]+"/"+result[1]; } if (operator == "*") { int[] result = FenShu_function.multiply(x, y) ; answers[i] = result[0]+"/"+result[1]; } if (operator == "/") { int[] result = FenShu_function.divide(x, y); if (result[0]==0) {//分子为零的情况 answers[i] = "0"; } if (result[0]!=0&&result[1]==1) { answers[i]=""+result[0]; } else { answers[i] = result[0]+"/"+result[1]; } } } }
//Operate.java
package test1; import java.text.DecimalFormat; public class Operate { static int plus(int x, int y) { return x + y; }// 加法运算 static int subtract(int x, int y) { return x - y; }// 减法运算 static int multiply(int x, int y) { return x * y; }// 乘法运算 static int[] divide(int[] x, int[] y) { return FenShu_function.divide(x, y); }// 除法运算 }
//FenShu_function.java
package test1; import java.text.DecimalFormat; public class FenShu_function { public static int[] yuefen(int[] fenshu) { // 负责对函数进行约分 int a = fenshu[0]; if (fenshu[0] > fenshu[1]) { a = fenshu[1]; } while (!justify(fenshu)) { for (int i = 2; i < a; i++) { // 除以公约数 if (fenshu[0] % i == 0 && fenshu[1] % i == 0) { fenshu[0] /= i; fenshu[1] /= i; } } } return fenshu; } //产生返回一个分数 public static int[] create() { // TODO Auto-generated method stub int[] fenshu = new int[2]; fenshu[0] = (int) (Math.random() * 10);// fenzi fenshu[1] = (int) (Math.random() * 20) + 1;// fenmu return fenshu; } static int[] plus(int[] x, int[] y) { int n = x[1] * y[1]; int m = x[0] * y[1] + x[1] * y[0]; x[0] = m; x[1] = n; while (!justify(x)) { yuefen(x); } return x; }// 加法运算 static int[] subtract(int[] x, int[] y) { int n = x[1] * y[1]; int m = x[0] * y[1] - x[1] * y[0]; x[0] = m; x[1] = n; while (!justify(x)) { yuefen(x); } return x; }// 减法运算 static int[] multiply(int[] x, int[] y) { int m = x[0] * y[0]; int n = x[1] * y[1]; x[0] = m; x[1] = n; while (!justify(x)) { yuefen(x); } return x; }// 乘法运算 static int[] divide(int[] x, int[] y) { int a = y[0]; y[0] = y[1]; y[1] = a; x = multiply(x, y); while (!justify(x)) { yuefen(x); } return x; }// 除法运算 public static boolean justify(int[] fenshu) { // 判断函数是否能够再化简 // TODO Auto-generated method stub int a = fenshu[0]; if (fenshu[0] > fenshu[1]) { a = fenshu[1]; } if (a < 0) { a = -a; } for (int i = 2; i <= a; i++) { if (fenshu[0] % i == 0 && fenshu[1] % i == 0) { return false; // 还没有除尽 } } return true; } }
实验小结:
通过这次的实验作业我认识到了自己的很多不足,其中也包括对于编程语言的掌握还不够熟悉,对于git新工具的初次尝试花了不少时间但是也的确使得我的每次编程变得目的更加明确、思路也更加清楚。但是因为在开始试验之前没有仔细的想好大概框架就慌慌张的动手,使得思路断断续续,框架也乱七八糟”磨刀不误砍柴工”,以后要在做事前有清晰明确的框架目标,方便在作业过程中及时纠正自己的方向。另外,还有一点就是不能只顾埋头一股脑的编程,在遇到困难解决不了时应该学会查找资料啊,他山之石可以攻玉,在网上查找优秀简洁的代码是很有益处的。最后还有一点,要提高代码的复用性,在我的代码中还有很多地方还要改进的,比如添加3个运算数运算、还不能识别小数与分数是否相等(如0.5和1/2),还没有利用Java面向对象的编程思想,对过程化的编程依赖较重。
总结以下几点:
1)、事前要仔细打草稿
2)、提高代码的复用
3)、要提高代码简洁性
4)、对程序的功能要分开,便于以后改进功能