练习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^)/~

 

posted on 2015-04-07 10:58  50林欢雯  阅读(209)  评论(0编辑  收藏  举报

导航