练习5.1——四则运算 测试与封装(更新版)

主函数:

  1 package h2;
  2 
  3 import java.text.DecimalFormat;
  4 import java.util.Scanner;
  5 import java.util.regex.Pattern;
  6 
  7 import Excep.YichangException;
  8 /*
  9  * 1.定制数量
 10  * 2.控制是否有乘除法
 11  * 3.控制数值范围
 12  * 4.定制真分数练习题
 13  * 5.校检用户输入
 14  * 6.输出答题正确率
 15  */
 16 public class Main {
 17     public static int max = 10;// 控制算式个数
 18     public static String[] staticanser = new String[max];// 标准答案
 19     public static DecimalFormat decimal = new DecimalFormat("#.##");
 20     
 21     
 22     // 求最大公约数
 23     private static int calcMaxSubmultiple(int num1, int num2) {
 24         num1=Math.abs(num1);//防止负数时求不得最大公约数。
 25         num2=Math.abs(num2);
 26         int min = Math.min(num1, num2);
 27         int maxSubmultiple = 1;
 28         for (int i = min; i >= 1; i--) {
 29             if (num1 % i == 0 && num2 % i == 0)
 30             {
 31                 maxSubmultiple = i;
 32                 break;
 33             }
 34             
 35         }
 36         return maxSubmultiple;
 37     }
 38 //主函数
 39     public static void main(String[] args)  {
 40         
 41         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 42         int[] no = new int[4];// 操作符地址
 43         int useno = 0;// 控制操作符
 44         int n = 3;// 操作数个数(随机)
 45         int[] num1 = new int[10];// 操作数
 46         char opp;// 判断是否需要乘除法
 47         char real;// 判断是否需要真分数的题目
 48         int[] cs = { 1, 100 };// 数值范围
 49         String[] useranser = new String[max];// 用户输入的答案
 50         
 51         
 52         int f = 0;// 控制输出真分数的操作符
 53         int count = 0;// 统计答题正确的数量
 54         
 55         int s1 = 1;// 分子通分
 56         int ss1 = 1;// 分子通分
 57         int s2 = 1;// 分母通分
 58         int result = 0;// 分子计算
 59         int gys;// 最大公约数
 60         int ff = 0;// 分数除法,分子为0标志位
 61         int fff=0;//
 62         String zjfz = new String();// 最简分子
 63         String zjfm = new String();// 最简分母
 64         Pattern pattern = Pattern.compile("[0-9]*"); // 限定输入算式数量输入的必须是数字
 65 
 66         Scanner in = new Scanner(System.in);
 67          //定制要求 
 68         System.out.print("请输入需定制的算式数量(1-20):");// 1.定制数量
 69         do {
 70             String str = in.nextLine();
 71             if (pattern.matcher(str).matches()) {// 如果输入的是数字就执行
 72                 max = Integer.parseInt(str);
 73                 if(max<=20&&max>0)
 74                 {
 75                     break;
 76                 }
 77                 else
 78                 {
 79                     System.out.print("你输入的范围有误,请重新输入:");
 80                 }
 81                 
 82             } else {                                                                       
 83                 System.out.print("你输入的不是数字,请重新输入:");
 84             }
 85         } while (true);
 86 
 87     
 88         System.out.print("是否需要乘除法(Y/N):");// 2.控制乘除参数
 89         do {
 90             opp = in.next().charAt(0);
 91             if (opp == 'Y' || opp == 'y') {
 92                 useno = 4;
 93                 break;
 94             } else if (opp == 'N' || opp == 'n') {
 95                 useno = 2;
 96                 break;
 97             } else {
 98                 System.out.print("输入错误,请重新输入:");
 99             }
100         } while (true);
101 
102         System.out.print("参数范围(eg:1,100):");// 3.控制数值范围
103         String str = new String();
104         int sr = 0;//判断循环结束
105         in.nextLine();// 过滤掉上面.next()方面的回车。
106         do {
107             try {
108                 str = in.nextLine();
109                 String[] ss = new String[2];
110                 ss = str.split(",");
111                 cs[0] = Integer.valueOf(ss[0]);
112                 cs[1] = Integer.valueOf(ss[1]);
113                 sr = 1;
114             } catch (Exception e) {
115                 System.out.print("输入格式错误,请重新输入:");
116             }
117         } while (sr != 1);
118 
119 
120         System.out.print("是否增加真分数练习题(Y/N):");// 4.真分数题目
121          do {
122              real = in.next().charAt(0);
123              if ( real == 'Y' || real == 'y') {
124                  
125                  break;
126              } else if ( real == 'N' || real == 'n') {
127                 break;
128              } else {
129                  System.out.print("输入错误,请重新输入:");
130              }
131          } while (true);
132 
133          //----------------题目-----------------------
134         System.out.println();
135         System.out.println("                2014-2015学年度第一单元测试卷");
136         System.out
137                 .println("班级:             姓名:             座号:          得分:                  ");
138         System.out.println();
139         System.out.println("一、请认真仔细地计算下面各题。(小数请保留小数点后两位)");
140         System.out.println();
141         Core c1=new Core();
142         for (int i = 0; i < max; i++) {
143 
144             System.out.print("(" + (i + 1) + ") ");
145             n = (int) (Math.random() * 4 + 2);// 2-5个操作数
146             for (int j = 0; j < n; j++) {
147                 num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值
148             }
149             for (int k = 0; k < n - 1; k++) {
150                 no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符
151                 if(no[k]==4&&num1[k+1]==0){
152                     do{
153                     num1[k+1]=(int) (Math.random() * (cs[1] - cs[0]) + cs[0]);//如果除号后为0,则重新取数。
154                     }while(num1[k+1]==0);
155                 }
156             }
157             for (int h = 0; h < n; h++) {
158                 if (h != n - 1) {
159                     if(num1[h]<0)
160                     {
161                         System.out.print("("+num1[h]+")");
162                         System.out.print(op[no[h]]);
163                     }
164                     else{
165                     System.out.print(num1[h]);
166                     System.out.print(op[no[h]]);
167                     }
168                 } else {
169                     if(num1[h]<0)
170                     {
171                         System.out.print("("+num1[h]+")=");
172                     }
173                     else
174                       System.out.print(num1[h] + "=");
175                 }
176             }
177             System.out.println();
178                 c1.calcute(num1, op, no, n);
179         }
180 
181         
182 
183         
184         
185         
186         // 学生答题模块
187         System.out.println("==================答题分割线=========================");
188         for (int i = 0; i < max; i++) {
189             System.out.print((i + 1) + ":");
190             useranser[i]=in.next();
191             if (useranser[i].equalsIgnoreCase(staticanser[i])) {
192                 count++;
193             }
194         }
195         System.out.println("标准答案为:");
196         for (int i = 0; i < max; i++) {
197             System.out.println((i + 1) + ":" + staticanser[i]);
198         }
199         System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100))
200                 + "%");
201         System.out.println("==================答题分割线=========================");
202 
203 //真分数     
204         if (real == 'Y' || real == 'y') {
205             System.out.println("二、请计算下列真分数算式。(无法计算请填null)");
206             System.out.println();
207             for (int i = 0; i < max; i++) {
208                 System.out.print("(" + (i + 1) + ") ");
209                 for (int j = 0; j < 2; j++)// (第一个真分数)
210                 {
211                     num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值
212                     if (j == 1 ) {
213                         while (num1[j - 1] >num1[j]||num1[j]== 0) {
214                             num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值
215                         }
216                     }
217                 }
218                 for (int j = 2; j < 4; j++)// (第二个真分数)
219                 {
220                     num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值
221                     if (j == 3) {
222                         while (num1[j - 1] >num1[j]||num1[j]== 0) {
223                             num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值
224                         }
225                     }
226                 }
227 
228                 for (int k = 0; k < 1; k++) {// 符号个数
229                     no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符
230                 }
231                 for (int h = 0; h < 4; h++) {// 2个真分数
232                     if (h % 2 == 0)
233                         System.out.print(("(" + num1[h] + "/"));
234                     else if (h % 2 == 1) {
235                         System.out.print(num1[h] + ")");
236                         if (f < 1) {// 控制只输出一个操作符
237                             System.out.print(op[no[f]]);
238                             f++;
239                         } else
240                             System.out.println("=");
241 
242                     }
243                 }
244 
245                 f = 0;
246                 //计算第二大题标准答案
247                 count=0;
248                 
249             }
250 
251             // 答题模板
252             System.out.println("==================答题分割线=========================");
253             for (int i = 0; i < max; i++) {
254                 System.out.print((i + 1) + ":");
255                 useranser[i] = in.next();
256                 if (useranser[i].equals(staticanser[i])) {
257                     count++;
258                 }
259             }
260             System.out.println("标准答案为:");
261             for (int i = 0; i < max; i++) {
262                 System.out.println((i + 1) + ":" + staticanser[i]);
263             }
264             System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100))
265                     + "%");
266             System.out
267                     .println("==================答题分割线=========================");
268         }
269 
270     }
271 }
View Code

封装Core类实现计算功能:

 1 package h2;
 2 
 3 import Excep.YichangException;
 4 
 5 public class Core {
 6     int sign; // 累加运算时的符号
 7     float left, right;// 保存蹭结果
 8     int i = 0;
 9     float result;
10 
11     public void calcute(int[] num1, char[] op, int[] no, int n)
12              {
13         // 一个算式中的所有数字num1,符号op,随机产生的符号下标no,随机产生的算式操作数个数n.
14         // // 计算第一大题答案
15             for (int h = 0; h < n - 1; h++) {
16                 if ((no[h] == 4) && (num1[h + 1] == 0)) {
17                     throw new ArithmeticException();
18                 }
19             }
20             left = 0;
21             right = num1[0];
22             sign = 1;
23             for (int g = 0; g < n - 1; g++) {
24                 switch (op[no[g]]) {
25                 case '+':
26                     left = left + sign * right;
27                     sign = 1;
28                     right = num1[g + 1];
29                     break;
30                 case '-':
31                     left = left + sign * right;
32                     sign = -1;
33                     right = num1[g + 1];
34                     break;
35                 case '*':
36                     right = right * num1[g + 1];
37                     break;
38                 case '/':
39                     right = right / num1[g + 1];
40                     break;
41                 }
42             }
43             result = left + sign * right;
44             Main.staticanser[i] = String.valueOf(Main.decimal.format(left+ sign * right));
45             i++;
46     }
47 
48     public float getResult() {
49         return this.result;
50     }
51 }
View Code

测试类:

  1 package h1;
  2 
  3 import static org.junit.Assert.*;
  4 
  5 import org.junit.Assert;
  6 import org.junit.Test;
  7 
  8 import Excep.YichangException;
  9 import h2.Core;
 10 
 11 public class CoreTest {
 12     @Test
 13     public void testAdd() {// 加法
 14         int n = 3;// 操作数个数
 15         int[] num1 = { 1, 2, 3 };// 操作数
 16         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 17         int[] no = { 1, 1 };// 操作符下标
 18         Core c = new Core();
 19         c.calcute(num1, op, no, n);
 20         float r = c.getResult();
 21         System.out.println(r);
 22         assertEquals(6, r, 0.1);
 23     }
 24 
 25     @Test
 26     public void testJian() {// 减法
 27         int n = 3;// 操作数个数
 28         int[] num1 = { 1, 2, 3 };// 操作数
 29         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 30         int[] no = { 2, 2 };// 操作符下标
 31         Core c = new Core();
 32         c.calcute(num1, op, no, n);
 33         float r = c.getResult();
 34         System.out.println(r);
 35         assertEquals(-4, r, 0.1);
 36     }
 37 
 38     @Test
 39     public void testMulti() {// 乘法
 40         int n = 3;// 操作数个数
 41         int[] num1 = { 2, 2, 3 };// 操作数
 42         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 43         int[] no = { 3, 3 };// 操作符下标
 44         Core c = new Core();
 45         c.calcute(num1, op, no, n);
 46         float r = c.getResult();
 47         System.out.println(r);
 48         assertEquals(12, r, 0.1);
 49     }
 50 
 51     @Test
 52     public void testDiv() {// 除法
 53         int n = 2;// 操作数个数
 54         int[] num1 = { 2, 4 };// 操作数
 55         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 56         int[] no = { 4 };// 操作符下标
 57         Core c = new Core();
 58         c.calcute(num1, op, no, n);
 59         float r = c.getResult();
 60         System.out.println(r);
 61         assertEquals(0.5, r, 0.1);
 62     }
 63 
 64     @Test
 65     public void testNormal() {// 混合运算
 66         int n = 4;// 操作数个数
 67         int[] num1 = { 1, 2, 3, 2 };// 操作数
 68         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 69         int[] no = { 1, 3, 4 };// 操作符下标
 70         Core c = new Core();
 71         c.calcute(num1, op, no, n);
 72         float r = c.getResult();
 73         System.out.println(r);
 74         assertEquals(4, r, 0.1);
 75     }
 76 
 77     @Test(expected = ArithmeticException.class)
 78     public void testZero() {// 除以零
 79         int n = 3;// 操作数个数
 80         int[] num1 = { 1, 0, 3 };// 操作数
 81         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 82         int[] no = { 4, 1 };// 操作符下标
 83         Core c = new Core();
 84         c.calcute(num1, op, no, n);
 85     }
 86 
 87     @Test
 88     public void dealZero() {// 除以零(处理异常)
 89         int n = 3;// 操作数个数
 90         int[] num1 = { 1, 0, 3 };// 操作数
 91         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
 92         int[] no = { 4, 1 };// 操作符下标
 93         Core c = new Core();
 94         try {
 95             c.calcute(num1, op, no, n);// 运算1/0+3
 96         } catch (Exception e) {
 97             System.out.println("除数不能为0");
 98         }
 99     }
100     
101     
102     @Test
103     public void testUnnormal2() {// 非法输入
104         int n = 4;// 操作数个数
105         int[] num1 = { 1, 2, 3, 2 };// 操作数
106         char[] op = { ' ', '+', '-', '*', '/' };// 操作符
107         int[] no = { 1, 3, 5};// 操作符下标--------越界
108         Core c = new Core();
109         try {
110             c.calcute(num1, op, no, n);// 运算1+2*3/2
111             float r = c.getResult();
112             System.out.println(r);
113         } catch (Exception e) {
114             System.out.println("下标越界,操作符下标越界");
115         }
116     }
117 
118 }
View Code

截图:

 

总结:

更新处理了一些奇怪的异常(操作数下标填了个5)。。以及除数为零异常。

用户输入部分未能封装成一个类,但异常处理都有。尝试过,但是出错很多。还没能彻底实现。在总的程序来看,调用Core类时其实是不会出现除数为零或者其他异常的。

 

 

 

 

posted on 2015-05-07 18:01  50林欢雯  阅读(219)  评论(3编辑  收藏  举报

导航