练习5.1——四则运算 测试与封装
主程序 package com.h2; import java.text.DecimalFormat; import java.util.Scanner; import java.util.regex.Pattern; /* * 1.定制数量 * 2.控制是否有乘除法 * 3.控制数值范围 * 4.定制真分数练习题 * 5.校检用户输入 * 6.输出答题正确率 */ public class Main { public static int max = 10;// 控制算式个数 public static String[] staticanser = new String[max];// 标准答案 public static DecimalFormat decimal = new DecimalFormat("#.##"); // 求最大公约数 private static int calcMaxSubmultiple(int num1, int num2) { num1=Math.abs(num1);//防止负数时求不得最大公约数。 num2=Math.abs(num2); int min = Math.min(num1, num2); int maxSubmultiple = 1; for (int i = min; i >= 1; i--) { if (num1 % i == 0 && num2 % i == 0) { maxSubmultiple = i; break; } } return maxSubmultiple; } //主函数 public static void main(String[] args) { char[] op = { ' ', '+', '-', '*', '/' };// 操作符 int[] no = new int[4];// 操作符地址 int useno = 0;// 控制操作符 int n = 3;// 操作数个数(随机) int[] num1 = new int[10];// 操作数 char opp;// 判断是否需要乘除法 char real;// 判断是否需要真分数的题目 int[] cs = { 1, 100 };// 数值范围 String[] useranser = new String[max];// 用户输入的答案 int f = 0;// 控制输出真分数的操作符 int count = 0;// 统计答题正确的数量 int s1 = 1;// 分子通分 int ss1 = 1;// 分子通分 int s2 = 1;// 分母通分 int result = 0;// 分子计算 int gys;// 最大公约数 int ff = 0;// 分数除法,分子为0标志位 int fff=0;// String zjfz = new String();// 最简分子 String zjfm = new String();// 最简分母 Pattern pattern = Pattern.compile("[0-9]*"); // 限定输入算式数量输入的必须是数字 Scanner in = new Scanner(System.in); //定制要求 System.out.print("请输入需定制的算式数量(1-20):");// 1.定制数量 do { String str = in.nextLine(); if (pattern.matcher(str).matches()) {// 如果输入的是数字就执行 max = Integer.parseInt(str); if(max<=20&&max>0) { break; } else { System.out.print("你输入的范围有误,请重新输入:"); } } else { System.out.print("你输入的不是数字,请重新输入:"); } } while (true); System.out.print("是否需要乘除法(Y/N):");// 2.控制乘除参数 do { opp = in.next().charAt(0); if (opp == 'Y' || opp == 'y') { useno = 4; break; } else if (opp == 'N' || opp == 'n') { useno = 2; break; } else { System.out.print("输入错误,请重新输入:"); } } while (true); System.out.print("参数范围(eg:1,100):");// 3.控制数值范围 String str = new String(); int sr = 0;//判断循环结束 in.nextLine();// 过滤掉上面.next()方面的回车。 do { try { str = in.nextLine(); String[] ss = new String[2]; ss = str.split(","); cs[0] = Integer.valueOf(ss[0]); cs[1] = Integer.valueOf(ss[1]); sr = 1; } catch (Exception e) { System.out.print("输入格式错误,请重新输入:"); } } while (sr != 1); System.out.print("是否增加真分数练习题(Y/N):");// 4.真分数题目 do { real = in.next().charAt(0); if ( real == 'Y' || real == 'y') { break; } else if ( real == 'N' || real == 'n') { break; } else { System.out.print("输入错误,请重新输入:"); } } while (true); //----------------题目----------------------- System.out.println(); System.out.println(" 2014-2015学年度第一单元测试卷"); System.out .println("班级: 姓名: 座号: 得分: "); System.out.println(); System.out.println("一、请认真仔细地计算下面各题。(小数请保留小数点后两位)"); System.out.println(); Core c1=new Core(); for (int i = 0; i < max; i++) { System.out.print("(" + (i + 1) + ") "); n = (int) (Math.random() * 4 + 2);// 2-5个操作数 for (int j = 0; j < n; j++) { num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 } for (int k = 0; k < n - 1; k++) { no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符 if(no[k]==4&&num1[k+1]==0){ do{ num1[k+1]=(int) (Math.random() * (cs[1] - cs[0]) + cs[0]);//如果除号后为0,则重新取数。 }while(num1[k+1]==0); } } for (int h = 0; h < n; h++) { if (h != n - 1) { if(num1[h]<0) { System.out.print("("+num1[h]+")"); System.out.print(op[no[h]]); } else{ System.out.print(num1[h]); System.out.print(op[no[h]]); } } else { if(num1[h]<0) { System.out.print("("+num1[h]+")="); } else System.out.print(num1[h] + "="); } } System.out.println(); c1.calcute(num1, op, no, n);//计算答案 } // 学生答题模块 System.out.println("==================答题分割线========================="); for (int i = 0; i < max; i++) { System.out.print((i + 1) + ":"); useranser[i]=in.next(); if (useranser[i].equalsIgnoreCase(staticanser[i])) { count++; } } System.out.println("标准答案为:"); for (int i = 0; i < max; i++) { System.out.println((i + 1) + ":" + staticanser[i]); } System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100)) + "%"); System.out.println("==================答题分割线========================="); //真分数 if (real == 'Y' || real == 'y') { System.out.println("二、请计算下列真分数算式。(无法计算请填null)"); System.out.println(); for (int i = 0; i < max; i++) { System.out.print("(" + (i + 1) + ") "); for (int j = 0; j < 2; j++)// (第一个真分数) { num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 if (j == 1 ) { while (num1[j - 1] >num1[j]||num1[j]== 0) { num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 } } } for (int j = 2; j < 4; j++)// (第二个真分数) { num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 if (j == 3) { while (num1[j - 1] >num1[j]||num1[j]== 0) { num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 } } } for (int k = 0; k < 1; k++) {// 符号个数 no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符 } for (int h = 0; h < 4; h++) {// 2个真分数 if (h % 2 == 0) System.out.print(("(" + num1[h] + "/")); else if (h % 2 == 1) { System.out.print(num1[h] + ")"); if (f < 1) {// 控制只输出一个操作符 System.out.print(op[no[f]]); f++; } else System.out.println("="); } } f = 0; //计算第二大题标准答案 count=0; } // 答题模板 System.out.println("==================答题分割线========================="); for (int i = 0; i < max; i++) { System.out.print((i + 1) + ":"); useranser[i] = in.next(); if (useranser[i].equals(staticanser[i])) { count++; } } System.out.println("标准答案为:"); for (int i = 0; i < max; i++) { System.out.println((i + 1) + ":" + staticanser[i]); } System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100)) + "%"); System.out .println("==================答题分割线========================="); } } }
1 将计算功能封装成Core类 2 3 4 package com.h2; 5 6 public class Core { 7 int sign; // 累加运算时的符号 8 float left, right;// 保存蹭结果 9 int i=0; 10 float result; 11 public void calcute(int[] num1,char[] op,int[] no,int n){ 12 //一个算式中的所有数字num1,符号op,随机产生的符号下标no,随机产生的算式操作数个数n. 13 // // 计算第一大题答案 14 for (int h = 0; h < n - 1; h++){ 15 if((no[h]==4)&&(num1[h+1]==0)){ 16 throw new ArithmeticException(); 17 } 18 } 19 left = 0; 20 right = num1[0]; 21 sign = 1; 22 for (int g = 0; g < n - 1; g++) { 23 switch (op[no[g]]) { 24 case '+': 25 left = left + sign * right; 26 sign = 1; 27 right = num1[g + 1]; 28 break; 29 case '-': 30 left = left + sign * right; 31 sign = -1; 32 right = num1[g + 1]; 33 break; 34 case '*': 35 right = right * num1[g + 1]; 36 break; 37 case '/': 38 right = right / num1[g + 1]; 39 break; 40 } 41 } 42 result=left + sign * right; 43 Main.staticanser[i] = String.valueOf(Main.decimal.format(left + sign * right)); 44 i++; 45 } 46 47 public float getResult(){ 48 return this.result; 49 } 50 }
1 根据助教提示做出测试类CoreTest 2 3 4 package com.h1; 5 6 import static org.junit.Assert.*; 7 8 import org.junit.Assert; 9 import org.junit.Test; 10 11 import com.h2.Core; 12 13 public class CoreTest { 14 @Test 15 public void testAdd() {// 加法 16 int n = 3;// 操作数个数 17 int[] num1 = { 1, 2, 3 };// 操作数 18 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 19 int[] no = { 1, 1 };// 操作符下标 20 Core c = new Core(); 21 c.calcute(num1, op, no, n);// 运算1+2+3 22 int r = (int) c.getResult(); 23 System.out.println(r); 24 assertEquals(6, r); 25 } 26 27 @Test 28 public void testJian() {// 减法 29 int n = 3;// 操作数个数 30 int[] num1 = { 1, 2, 3 };// 操作数 31 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 32 int[] no = { 2, 2 };// 操作符下标 33 Core c = new Core(); 34 c.calcute(num1, op, no, n);// 运算1-2-3 35 int r = (int) c.getResult(); 36 System.out.println(r); 37 assertEquals(-4, r); 38 } 39 40 @Test 41 public void testMulti() {// 乘法 42 int n = 3;// 操作数个数 43 int[] num1 = { 2, 2, 3 };// 操作数 44 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 45 int[] no = { 3, 3 };// 操作符下标 46 Core c = new Core(); 47 c.calcute(num1, op, no, n);// 运算2*2*3 48 int r = (int) c.getResult(); 49 System.out.println(r); 50 assertEquals(12, r); 51 } 52 53 @Test 54 public void testDiv() {// 除法 55 int n = 2;// 操作数个数 56 int[] num1 = { 2, 2, 3 };// 操作数 57 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 58 int[] no = { 4 };// 操作符下标 59 Core c = new Core(); 60 c.calcute(num1, op, no, n);// 运算2/2 61 int r = (int) c.getResult(); 62 System.out.println(r); 63 assertEquals(1, r); 64 } 65 66 @Test 67 public void testNormal() {// 混合运算 68 int n = 3;// 操作数个数 69 int[] num1 = { 1, 2, 3 };// 操作数 70 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 71 int[] no = { 1, 3 };// 操作符下标 72 Core c = new Core(); 73 c.calcute(num1, op, no, n);// 运算1+2*3 74 int r = (int) c.getResult(); 75 System.out.println(r); 76 assertEquals(7, r); 77 } 78 79 @Test(expected = ArithmeticException.class) 80 public void testZero() {// 除以零 81 int n = 3;// 操作数个数 82 int[] num1 = { 1, 0, 3 };// 操作数 83 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 84 int[] no = { 4, 1 };// 操作符下标 85 Core c = new Core(); 86 c.calcute(num1, op, no, n);// 运算1/0+3 87 } 88 89 }
在测试类中共测试了简单的加法,减法,除法,乘法,和除数为零。
缺点:长整形等特殊的数,没有测试。但其实在实际的主程序中不会出现长整形的数。也不会出现除数为零的情况。
总结:稍微了解了程序设计,虽然学骑单车的时候摔了很多次,但最终我们有了进步。这是值得开心的事情。在整个测试中,我负责写封装,以及封装之后的测试类,小伙伴负责写黑白盒。截图、黑白盒等小伙伴会继续完善并发博客。
结对小伙伴:陈建:http://www.cnblogs.com/be-the-one/
由于五一要出发去远方,所以作业比较赶,感谢小伙伴的体谅,接下来就交给你了。