练习1---四则运算(最终版)
1 package 软件工程; 2 3 import java.math.RoundingMode; 4 import java.text.DecimalFormat; 5 import java.util.Scanner; 6 import java.util.regex.Pattern; 7 /* 8 * 1.定制数量 9 * 2.控制是否有乘除法 10 * 3.控制数值范围 11 * 4.定制真分数练习题 12 * 5.校检用户输入 13 * 6.输出答题正确率 14 */ 15 public class Main { 16 // 求最大公约数 17 private static int calcMaxSubmultiple(int num1, int num2) { 18 num1=Math.abs(num1);//防止负数时求不得最大公约数。 19 num2=Math.abs(num2); 20 int min = Math.min(num1, num2); 21 int maxSubmultiple = 1; 22 for (int i = min; i >= 1; i--) { 23 if (num1 % i == 0 && num2 % i == 0) 24 { 25 maxSubmultiple = i; 26 break; 27 } 28 29 } 30 return maxSubmultiple; 31 } 32 //主函数 33 public static void main(String[] args) { 34 int max = 10;// 控制算式个数 35 char[] op = { ' ', '+', '-', '*', '/' };// 操作符 36 int[] no = new int[4];// 操作符地址 37 int useno = 0;// 控制操作符 38 int n = 3;// 操作数个数(随机) 39 int[] num1 = new int[10];// 操作数 40 char opp;// 判断是否需要乘除法 41 char real;// 判断是否需要真分数的题目 42 int[] cs = { 1, 100 };// 数值范围 43 String[] useranser = new String[max];// 用户输入的答案 44 String[] staticanser = new String[max];// 标准答案 45 int sign; // 累加运算时的符号 46 float left, right;// 保存蹭结果 47 int f = 0;// 控制输出真分数的操作符 48 int count = 0;// 统计答题正确的数量 49 DecimalFormat decimal = new DecimalFormat("#.##"); 50 decimal.setRoundingMode(RoundingMode.HALF_UP); 51 52 int s1 = 1;// 分子通分 53 int ss1 = 1;// 分子通分 54 int s2 = 1;// 分母通分 55 int result = 0;// 分子计算 56 int gys;// 最大公约数 57 int ff = 0;// 分数除法,分子为0标志位 58 int fff=0;// 59 String zjfz = new String();// 最简分子 60 String zjfm = new String();// 最简分母 61 Pattern pattern = Pattern.compile("[0-9]*"); // 限定输入算式数量输入的必须是数字 62 63 Scanner in = new Scanner(System.in); 64 //定制要求 65 System.out.print("请输入需定制的算式数量:");// 1.定制数量 66 do { 67 String str = in.nextLine(); 68 if (pattern.matcher(str).matches()) {// 如果输入的是数字就执行 69 max = Integer.parseInt(str); 70 break; 71 } else { 72 System.out.print("你输入的不是数字,请重新输入:"); 73 } 74 } while (true); 75 76 77 System.out.print("是否需要乘除法(Y/N):");// 2.控制乘除参数 78 do { 79 opp = in.next().charAt(0); 80 if (opp == 'Y' || opp == 'y') { 81 useno = 4; 82 break; 83 } else if (opp == 'N' || opp == 'n') { 84 useno = 2; 85 break; 86 } else { 87 System.out.print("输入错误,请重新输入:"); 88 } 89 } while (true); 90 91 System.out.print("参数范围(eg:1,100):");// 3.控制数值范围 92 String str = new String(); 93 int sr = 0;//判断循环结束 94 in.nextLine();// 过滤掉上面.next()方面的回车。 95 do { 96 try { 97 str = in.nextLine(); 98 String[] ss = new String[2]; 99 ss = str.split(","); 100 cs[0] = Integer.valueOf(ss[0]); 101 cs[1] = Integer.valueOf(ss[1]); 102 sr = 1; 103 } catch (Exception e) { 104 System.out.print("输入格式错误,请重新输入:"); 105 } 106 } while (sr != 1); 107 108 109 System.out.print("是否增加真分数练习题(Y/N):");// 4.真分数题目 110 do { 111 real = in.next().charAt(0); 112 if ( real == 'Y' || real == 'y') { 113 114 break; 115 } else if ( real == 'N' || real == 'n') { 116 break; 117 } else { 118 System.out.print("输入错误,请重新输入:"); 119 } 120 } while (true); 121 122 //----------------题目----------------------- 123 System.out.println(); 124 System.out.println(" 2014-2015学年度第一单元测试卷"); 125 System.out 126 .println("班级: 姓名: 座号: 得分: "); 127 System.out.println(); 128 System.out.println("一、请认真仔细地计算下面各题。(小数请保留小数点后两位)"); 129 System.out.println(); 130 for (int i = 0; i < max; i++) { 131 132 System.out.print("(" + (i + 1) + ") "); 133 n = (int) (Math.random() * 3 + 2);// 2-4个操作数 134 for (int j = 0; j < n; j++) { 135 num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 136 } 137 for (int k = 0; k < n - 1; k++) { 138 no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符 139 if(no[k]==4&&num1[k+1]==0){ 140 do{ 141 num1[k+1]=(int) (Math.random() * (cs[1] - cs[0]) + cs[0]);//如果除号后为0,则重新取数。 142 }while(num1[k+1]==0); 143 } 144 } 145 for (int h = 0; h < n; h++) { 146 if (h != n - 1) { 147 System.out.print(num1[h]); 148 System.out.print(op[no[h]]); 149 } else { 150 System.out.print(num1[h] + "="); 151 } 152 } 153 System.out.println(); 154 155 // // 计算第一大题答案 156 left = 0; 157 right = num1[0]; 158 sign = 1; 159 160 for (int g = 0; g < n - 1; g++) { 161 switch (op[no[g]]) { 162 case '+': 163 left = left + sign * right; 164 sign = 1; 165 right = num1[g + 1]; 166 break; 167 case '-': 168 left = left + sign * right; 169 sign = -1; 170 right = num1[g + 1]; 171 break; 172 case '*': 173 right = right * num1[g + 1]; 174 break; 175 case '/': 176 right = right / num1[g + 1]; 177 break; 178 } 179 } 180 staticanser[i] = String.valueOf(decimal.format(left + sign * right)); 181 // System.out.println((i+1)+":"+staticanser[i]); 182 } 183 184 // 学生答题模块 185 System.out.println("==================答题分割线========================="); 186 for (int i = 0; i < max; i++) { 187 System.out.print((i + 1) + ":"); 188 useranser[i] = in.next(); 189 if (useranser[i].equalsIgnoreCase(staticanser[i])) { 190 count++; 191 } 192 } 193 System.out.println("标准答案为:"); 194 for (int i = 0; i < max; i++) { 195 System.out.println((i + 1) + ":" + staticanser[i]); 196 } 197 System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100)) 198 + "%"); 199 System.out.println("==================答题分割线========================="); 200 201 //真分数 202 if (real == 'Y' || real == 'y') { 203 System.out.println("二、请计算下列真分数算式。(无法计算请填null)"); 204 System.out.println(); 205 for (int i = 0; i < max; i++) { 206 System.out.print("(" + (i + 1) + ") "); 207 for (int j = 0; j < 2; j++)// (第一个真分数) 208 { 209 num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 210 if (j == 1 ) { 211 while (num1[j - 1] >num1[j]||num1[j]== 0) { 212 num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 213 } 214 } 215 } 216 for (int j = 2; j < 4; j++)// (第二个真分数) 217 { 218 num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 219 if (j == 3) { 220 while (num1[j - 1] >num1[j]||num1[j]== 0) { 221 num1[j] = (int) (Math.random() * (cs[1] - cs[0]) + cs[0]);// 控制随机数数值 222 } 223 } 224 } 225 226 for (int k = 0; k < 1; k++) {// 符号个数 227 no[k] = (int) (Math.random() * useno + 1);// 随机产生操作符 228 } 229 for (int h = 0; h < 4; h++) {// 2个真分数 230 if (h % 2 == 0) 231 System.out.print(("(" + num1[h] + "/")); 232 else if (h % 2 == 1) { 233 System.out.print(num1[h] + ")"); 234 if (f < 1) {// 控制只输出一个操作符 235 System.out.print(op[no[f]]); 236 f++; 237 } else 238 System.out.println("="); 239 240 } 241 } 242 243 f = 0; 244 //计算第二大题标准答案 245 count=0; 246 for (int g = 0; g < 1; g++) { 247 s1 = num1[0] * num1[3]; 248 ss1 = num1[1] * num1[2]; 249 s2 = num1[1] * num1[3];//分母 250 ff=0; 251 fff=0; 252 switch (op[no[g]]) { 253 case '+': 254 result = s1 + ss1;//分子 255 gys = calcMaxSubmultiple(result, s2);// 除以公约数得到最简分数 256 //System.out.println(gys); 257 zjfz = String.valueOf(result / gys); 258 zjfm = String.valueOf(s2 / gys); 259 break; 260 case '-': 261 result = s1 - ss1; 262 gys = calcMaxSubmultiple(result, s2); 263 //System.out.println(gys); 264 zjfz = String.valueOf(result / gys); 265 zjfm = String.valueOf(s2 / gys); 266 break; 267 case '*': 268 result = num1[0] * num1[2]; 269 gys = calcMaxSubmultiple(result, s2); 270 //System.out.println(gys); 271 if(num1[0] == 0 || num1[2] == 0) 272 { 273 fff=1; 274 } 275 zjfz = String.valueOf(result / gys); 276 zjfm = String.valueOf(s2 / gys); 277 break; 278 case '/':// 乘以倒数 279 result = num1[0] * num1[3]; 280 s2 = num1[1] * num1[2]; 281 gys = calcMaxSubmultiple(result, s2); 282 283 //System.out.println(gys); 284 if (num1[0] == 0 || num1[2] == 0) { 285 ff = 1; 286 } 287 zjfz = String.valueOf(result / gys); 288 zjfm = String.valueOf(s2 / gys); 289 break; 290 } 291 } 292 if (ff == 1) { 293 staticanser[i] = "null";//当第二个数的分子为零时无法做除法 294 }else if(fff==1){ 295 staticanser[i] = "0"; 296 }else if(zjfz==zjfm){ 297 staticanser[i] = "1"; 298 }else if(zjfm.equalsIgnoreCase("1")){ 299 staticanser[i] = zjfz; 300 }else{ 301 staticanser[i] = zjfz + "/" + zjfm; 302 } 303 // System.out.println((i+1)+":"+staticanser[i]); 304 } 305 306 // 答题模板 307 System.out.println("==================答题分割线========================="); 308 for (int i = 0; i < max; i++) { 309 System.out.print((i + 1) + ":"); 310 useranser[i] = in.next(); 311 if (useranser[i].equals(staticanser[i])) { 312 count++; 313 } 314 } 315 System.out.println("标准答案为:"); 316 for (int i = 0; i < max; i++) { 317 System.out.println((i + 1) + ":" + staticanser[i]); 318 } 319 System.out.println("答题正确率为:" + String.valueOf(decimal.format(((float) count / (float) max) * 100)) 320 + "%"); 321 System.out 322 .println("==================答题分割线========================="); 323 } 324 325 } 326 }
+++++++++++++++++++++++++++++++++++++++++++总结++++++++++++++++++++++++++++++++++++++++++++++++=
1.一开始使用DecimalFormat decimal = new DecimalFormat("#.##");
decimal.format(...); 进行截取小数点后的位数时,
发现仍然有有些数不会自动四舍五入,后来百度了一下,找到了解决方法。
decimal.setRoundingMode(RoundingMode.HALF_UP);//加入这个语句:设置舍入模式
2.分数计算时,发现有部分的分数不能约分到最简,后来发现如果算出来的数是负数,那么calcMaxSubmultiple(int num1, int num2) // 求最大公约数
这个方法里面不符合循环条件,for (int i = min; i >= 1; i--)
因此,先求绝对值,再进行求最大公约数。
3.分数计算时要判断很多东西,首先是分数分母不为零;其次是,当分子为零时,乘法为零,除法无法计算;最后是标准答案格式,当分子分母相同时要输出“1”,当结果分母为“1”时,只输出分子。
4.根据老师指出的BUG,已进行修改。
缺点:首先是代码没有封装,所以看起来有点乱。
其次是觉得把所有的定义都放在最前面(C语言做法)不太好,以后的编程会改进。
总结了几次出现的问题一步一步地解决,解决完感觉超棒的~~~~~~~~~~yo 呼~~~~\(^o^)/~