首页 > 代码库 > 四则运算三
四则运算三
上次的作业,四则运算三,在以前的基础上又有了新的需求。算术题目中不能产生复数,也就是所算术表达式如果有形如e1-e2的子表达式,那么e1>e2 。而且除法的结果可以表示为真分数或者带分数,每道题目不超过三个运算符。而且一次程序运行的结果不能产生重复的表达式,即任何两道题目不能通过有限次的加法交换和乘法交换变成统一到题目(其实我觉得如果两个表达式需要经过加法交换或者乘法交换变成同一道题,那么这两个题也不是重复的题目呀,因为这还需要涉及到交换律呀!)。最重要的是需要连接数据库,计算答案和判定对错。
程序设计思路
首先要考虑的问题是程序中生成的表达式应该存放在什么地方。就我看来不外乎两种方式,数组和字符串。我选择了字符串,因为在我看来,如果用数组存放不方便括号的处理(也许其他同学有办法,而且觉得数组好)。然后,因为如果有除法运算,结果需要表示为真分数或者带分数形式的字符串,所以在运算过程中必定会牵涉到有分数参与的计算。为了解决这个问题,需要用到分数类,这个类java中似乎没有提供(也许提供了我不知道),所以我自己编写了一个分数类,这个类需要拥有分数的加减乘除功能、比较大小功能等等。其实这一步我在四则运算二的任务重就已经完成了,只是有一点需要重新考虑,在表达式中假分数需要表示为带分数形式,这只需要重新编写toString()方法就行了。另外一个小问题(对我来说也是一个关键问题,解决这个问题候就解决了问题的一半),如何分辨表达式中的除号和分数的分数线。可能有人会说分数线和除号不都是一个意义吗?是的,分数线和除法符号在数学上就是一个意思,但是如果表达式中出现两个连续的除号(除号都用‘/’)例如a/b/c,那么究竟是a除以b除以c呢,还是a除以c分之b呢?老师要求在运算符和操作数之间留有空格,用来区分以上情况,但是这样求值会很困难,因为我是先构建表达式存放在字符串中,然后再求值。及反思所我还是想到了一个好办法 ,用标准的四则运算符号表示运算(﹢﹣×÷)表示即可,反正这只是在字符串中的一个表现形式,不需要程序识别这些运算符。至于在程序中怎么输入这些符号,其实也简单,搜狗输入法可以输入一些特殊的字符。然后是程序的主体部分,求值。其实表达式求值没有什么难的,就是应用堆栈将中缀表达式化为后缀表达式,这些在数据结构中都学过。最后一个难题,怎么比较两个表达式是否重复。我想了很久还是想出来一个方法,这里我把算法列出来。设l1,l2是两个表达式。
- 如果l1,l2的值不相同,程序结束,返回false。
- 如果l1,l2的字符串相同,及表达式为一模一样,程序结束,返回true
- 如果l1,l2的值不相同且字符串不相同,这时我们要判断是否可以经过有限次加法或乘法交换得到相同的表达式。执行以下步骤:
(1) 如果l1,l2的操作数个数不相同,返回false,程序结束。
(2) 如果l1,l2的操作数个数相同且都为2,我们便可以方便的判断出这两个表达式是否相同。
(3) 如果l1,l2的操作数个数相同而且不为2,执行以下步骤:
1) 取l1,l2中最先运算的子表达式e1,e2.
2) 递归调用本算法比较e1,e2是否相同。
3) 如果e1,e2不相同,返回false,程序结束。
4) 如果e1,e2不相同,用e1,e2的结果替代原表达式中的e1,e2得到两个新的表达式n1,n2。递归调用本方法比较n1,n2是否相同,相同返回true,不相同返回false。
上面这个算法步骤比较复杂,其中还用到一些其他的步骤,比如如何取出表达式中最先运算的子表达式,如果计算表达式中操作数的个数等。这些都不是简单事。
程序代码
1 import java.util.ArrayList; 2 import java.util.Scanner; 3 //import java.util.Scanner; 4 5 public class Equation { 6 7 public static void main(String[] args) throws Exception { 8 // TODO Auto-generated method stub 9 Scanner scan = new Scanner(System.in); 10 boolean flag = false; 11 boolean ismul = false; 12 boolean withbrackets = false; 13 int num = 0; 14 int sum = 0; 15 int zhen = 0; 16 int fenzi = 0; 17 int fenmu = 0; 18 19 do{ 20 try{ 21 System.out.println("您需要多少个式子:"); 22 num = scan.nextInt(); 23 System.out.println("是否含有乘除法?(true/false)"); 24 ismul = scan.nextBoolean(); 25 System.out.println("操作数的个数:"); 26 sum = scan.nextInt(); 27 System.out.println("整数最大值:"); 28 zhen = scan.nextInt(); 29 System.out.println("分子最大值:"); 30 fenzi = scan.nextInt(); 31 System.out.println("分母最大值:"); 32 fenmu = scan.nextInt(); 33 System.out.println("是否包含括号:(true/false)"); 34 withbrackets = scan.nextBoolean();scan.nextLine(); 35 flag = false; 36 int[] correct = new int[num]; 37 int[] wrong = new int[num]; 38 int correctsum = 0; 39 int wrongsum = 0; 40 for(int index = 0;index<num; index++) 41 { 42 Equation s = new Equation(ismul,sum,zhen,fenzi,fenmu,withbrackets); 43 System.out.print((index+1)+":\t"+s.express +" = "); 44 String aws = scan.nextLine(); 45 if(aws.equals(s.value)){ 46 correct[correctsum++] = index+1; 47 }else{ 48 wrong[wrongsum++] = index+1; 49 } 50 } 51 if(correctsum>0) 52 { 53 System.out.print("正确"+correctsum+" correct("); 54 for(int j = 0; j < correctsum; j++){ 55 System.out.print(correct[j]); 56 if(j!=correctsum-1) 57 System.out.print(","); 58 else 59 System.out.println(")"); 60 } 61 } 62 if(wrongsum>0) 63 { 64 System.out.print("错误"+wrongsum+" wrong("); 65 for(int j = 0; j < wrongsum; j++){ 66 System.out.print(wrong[j]); 67 if(j!=wrongsum-1) 68 System.out.print(","); 69 else 70 System.out.println(")"); 71 } 72 } 73 }catch(Exception e){ 74 System.out.println("输入错误,请重新输入!"); 75 flag = true; 76 } 77 }while(flag); 78 scan.close(); 96 } 97 98 99 100 private String express,//表达式 101 value;//表达式结果 102 private int number;//操作数个数 103 public Equation(boolean incmul,int much,int zhen,int fenzi,int fenmu,boolean withbrackets) 104 {//incmul是否包含乘除法,much表示操作数的个数 105 if(much < 2) 106 much = 2; 107 number = much; 108 boolean tag = false; 109 do{ 110 try { 111 express = createExpress(incmul,much,zhen,fenzi,fenmu,withbrackets); 112 value =http://www.mamicode.com/ evaluation(express); 113 tag = false; 114 } catch (Exception e) { 115 tag = true; 116 } 117 }while(tag); 118 } 119 public Equation(){ 120 this(true,4,100,10,11,true); 121 } 122 public Equation(String exp){ 123 express = exp; 124 try { 125 this.value =http://www.mamicode.com/ evaluation(exp); 126 this.number= this.allFigure().length; 127 } catch (Exception e) { 128 this.express = null; 129 this.value = http://www.mamicode.com/null; 130 } 131 } 132 //setter and get 133 public String getExpress(){return express;} 134 public void setExpress(String ex){express = ex;} 135 public String getValue(){return value;} 136 public int getNumbers(){return number;} 137 public void setNumber(int n){number = n;} 138 public String toString(){ 139 return express+" = "+value; 140 } 141 public boolean equals(Equation another)//比较两个算式是否相同 142 { 143 if(this.express==null||this.value=http://www.mamicode.com/=null||another.express==null||another.value=http://www.mamicode.com/=null) 144 return false; 145 //如果两个等式的表达式相同 146 if(this.express.equals(another.express)) 147 return true; 148 //如果两个表达式的值不相同,则程序结束 149 if(!getValue().equals(another.getValue())) 150 return false; 151 else{ 152 //将表达式分解成数字串和操作符,TODO 如果表达式中没有空格将不能分开 153 String[] part1 = this.separateAll(); 154 String[] part2 = another.separateAll(); 155 int len1 = part1.length; 156 int len2 = part2.length; 157 //如果分开后的数组长度小于3,则程序出现异常,返回false 158 if(len1<3||len2<3) 159 return false; 160 //如果两个数组长度不相等,则原表达式不相等 161 if(len1!=len2) 162 return false; 163 //否则 164 else{ 165 //如果表达式包含一个操作符和两个操作数 166 if(len1==3){ 167 //如果两个表达式的操作数对应相同 168 if((part1[0].equals(part2[0])&&part1[2].equals(part2[2]))) 169 { 170 if(part1[1].equals(part2[1])) 171 return true; 172 else 173 return false; 174 } 175 //如果两个表达式的操作数交叉相同 176 else if(part1[0].equals(part2[2])&&part1[2].equals(part2[0])) 177 { 178 //如果两个表达式的操作符不相同 179 if(!part1[1].equals(part2[1])) 180 return false; 181 //操作符相同 182 else{ 183 //如果是加法或者乘法 184 if(part1[1].equals("﹢")||part1[1].equals("×")) 185 return true; 186 //如果是减法或者除法 187 else 188 return false; 189 } 190 } 191 //如果表达式的操作数不相同 192 else 193 return false; 194 } 195 //如果表达式操作符个数大于一且操作数大于二 196 else{ 197 //取两个表达式中优先级最高的子表达式 198 Equation e1 = this.precede(); 199 Equation e2 = another.precede(); 200 //比较两个子表达式是否相同 201 boolean tag = e1.equals(e2); 202 //如果子表达式不相同 203 if(!tag) 204 return tag; 205 //如果子表达式相同 206 else{ 207 //用子表达式的值取代子表达式在原式中的位置,构成新的两个表达式。 208 String newstr1 = this.express.replaceFirst(e1.express, e1.value); 209 newstr1 = removeBracket(newstr1,e1.value);//处理一个数由一对括号包围的情况 210 String newstr2 = another.express.replaceFirst(e2.express, e2.value); 211 newstr2 = removeBracket(newstr2,e1.value);//处理一个数由一对括号包围的情况 212 e1 = new Equation(newstr1); 213 e2 = new Equation(newstr2); 214 //比较两个新的表达式是否相同,且返回比较结果。 215 return e1.equals(e2); 216 } 217 } 218 } 219 } 220 } 221 /** 222 * 2017/3/19日增加removeBracket()方法 223 * 在去优先级最高的子表达式时,有可能子表达式被一对括号包含,但通过precede 224 * 方法取得的子表达式不含有括号。在equals方法中,用子表达式的值取代子表达式后 225 * 有可能出现一个数带有一个括号,该方法就是去掉这种情况 226 * */ 227 private static String removeBracket(String orign,String subvalue)//去掉包含单个数字的括号。 228 {//orign 是原来的表达式字符串形式被自表达式的值取代后的字符串,subvalue为子表达式的值 229 String str = new String(orign); 230 String regex = "("+subvalue+")"; 231 if(orign.indexOf(regex)>=0) 232 str = orign.replace(regex, subvalue); 233 234 return str; 235 } 236 private static String getFraction(int x,int y,int z)//生成一个分数 237 { 238 if(z == 0) 239 return "0"; 240 double f = Math.random();//随机数 241 Fraction fr = null;//声明一个分数 242 if(f < 0.3){//如果随机数的大于0.3生成一个分数 243 //随机数c表示分子 244 int c = (int)(Math.random()*y); 245 //随机数d表示分母,注意分母不能为零 246 int d = (int)(Math.random()*(z-1))+1; 247 try { 248 fr = new Fraction(c,d); 249 return fr.toString(); 250 } catch (Exception e) { 251 e.printStackTrace(); 252 } 253 }else{//否则生成一个整数 254 int c = (int)(Math.random()*x); 255 return ""+c; 256 } 257 return null; 258 } 259 private static String createExpress(boolean incmul,int num,int zhen,int fenzi,int fenmu,boolean withbrackets) 260 //生成一个表达式,incmul表示是否支持乘除法,num表示操作数的个数 261 { 262 if(num<2) 263 num = 2; 264 char[] operator = {‘﹢‘,‘﹣‘,‘ב,‘÷‘};//存放操作符的字符数组 265 if(!incmul)//如果不支持乘除法,将‘ב,‘÷‘替换为‘﹢‘,‘﹣‘ 266 { 267 operator[2] = ‘﹢‘; 268 operator[3] = ‘﹣‘; 269 } 270 String[] strArray = new String[num]; 271 char[] opeArray = new char[num-1]; 272 for(int i = 0; i < num; i++) 273 { 274 strArray[i] = getFraction(zhen,fenzi,fenmu); 275 if(i < num -1){ 276 int index = (int)(Math.random()*4); 277 opeArray[i] = operator[index]; 278 } 279 } 280 if(withbrackets) 281 insertBrackets(strArray,0,num-1); 282 String str = ""; 283 for(int i = 0; i < num; i++) 284 { 285 str += strArray[i]; 286 if(i < num-1) 287 str += " "+opeArray[i]+" "; 288 } 289 290 return str; 291 } 292 private static void insertBrackets(String[] exp,int index_1,int index_2) 293 { 294 /** 295 *2017/3/15日修改插入括号的方法,先生成操作数,然后将括号加到操作数中 296 */ 297 int y = index_2 - index_1; 298 if(y < 2) 299 return ; 300 int i = (int)(Math.random()*(y))+index_1; 301 int j = (int)(Math.random()*(y+1))+index_1; 302 if(i>j){ 303 i = i^j; 304 j = i^j; 305 i = i^j; 306 } 307 int x = j - i; 308 int z = exp.length-1; 309 if(x >= 1&&x!=z&&x!=y){ 310 exp[i] = "("+exp[i]; 311 exp[j] = exp[j]+")"; 312 } 313 314 315 insertBrackets(exp,index_1,i-1); 316 insertBrackets(exp,i,j); 317 insertBrackets(exp,j+1,index_2); 318 } 319 320 private static String evaluation(String express)throws Exception//计算表达式的结果 321 { 322 //构建两个栈,分别存放分数和操作符 323 java.util.Stack<Fraction> mstack = new java.util.Stack<Fraction>(); 324 java.util.Stack<Character> ostack=new java.util.Stack<Character>(); 325 326 boolean flag = false;//旗帜变量表示上一个分数是否压入了mStack栈中 327 express += "#"; 328 int i = 0,len = express.length(); 329 ostack.push(‘#‘); 330 String str = "";//中间字符串变量,用来读取表达式中的一个分数或者整数 331 332 while(i < len){ 333 char ch = express.charAt(i); 334 //当前字符为一个分数或者整数的一部分。 335 if((ch>=‘0‘ && ch<=‘9‘) || ch==‘/‘ || ch==‘\‘‘){ 336 str += ch; 337 flag = true;//数没有压入栈中 338 i++; 339 }else{//如果当前字符是空格或者操作符 340 if(flag){//如果上一个操作数还没有压入mStack栈,怎将其压入栈中 341 Fraction f = new Fraction(str); 342 mstack.push(f); 343 str = ""; 344 flag = false;//数字已经压入栈中 345 } 346 if(ch == ‘ ‘)//如果当前字符是空格则跳过这个字符 347 i++; 348 else{//以下为运算过程 349 char op = ostack.peek(); 350 char tag = compare(op,ch); 351 switch(tag){ 352 353 case ‘<‘: 354 ostack.push(ch);i++;break; 355 case ‘>‘: 356 Fraction b = mstack.pop(); 357 Fraction a = mstack.pop(); 358 char oo = ostack.pop(); 359 Fraction c = calcul(a,oo,b); 360 if(c.lessThan(new Fraction(0))) 361 throw new Exception("表达式"+a+oo+b+"的值为负数!"); 362 mstack.push(c);break; 363 case ‘=‘: 364 ostack.pop(); 365 i++; 366 break; 367 } 368 } 369 370 } 371 } 372 Fraction r = mstack.pop(); 373 return r.toString(); 374 } 375 private static Fraction calcul(Fraction a, char oo, Fraction b) throws Exception//a,b按照oo所代表的操作运算 376 { 377 // TODO Auto-generated method stub 378 if(oo == ‘﹢‘) 379 return a.add(b); 380 else if(oo == ‘﹣‘) 381 return a.reduce(b); 382 else if(oo == ‘ב) 383 return a.multiply(b); 384 else if(oo == ‘÷‘) 385 return a.divide(b); 386 return null; 387 } 388 private static char compare(char s,char t)//比较s,t的优先级 389 { 390 char tag=‘<‘; //临时变量,用来保存比较结果 391 switch(s){ 392 case ‘﹢‘: 393 if(t == ‘ב || t == ‘÷‘ || t == ‘(‘) 394 tag = ‘<‘; 395 else 396 tag = ‘>‘; 397 break; 398 case ‘﹣‘: 399 if(t == ‘ב || t == ‘÷‘ || t == ‘(‘) 400 tag = ‘<‘; 401 else 402 tag = ‘>‘; 403 break; 404 case ‘ב: 405 if(t == ‘(‘) 406 tag = ‘<‘; 407 else 408 tag = ‘>‘; 409 break; 410 case ‘÷‘: 411 if(t == ‘(‘) 412 tag = ‘<‘; 413 else 414 tag = ‘>‘; 415 break; 416 case ‘(‘: 417 if(t == ‘)‘) 418 tag = ‘=‘; 419 else if(t == ‘#‘) 420 break; 421 } 422 return tag; 423 } 424 425 public String[] separateAll() 426 { 427 String[] s = express.split("[\\s()]+"); 428 return s; 429 430 } 431 public Fraction[] allFigure() 432 { 433 String ss = express+" "; 434 int len = ss.length(),i=0; 435 boolean flag = false; 436 String str = ""; 437 ArrayList<Fraction> list = new ArrayList<Fraction>(); 438 do{ 439 char ch = ss.charAt(i); 440 //当前字符为一个分数或者整数的一部分。 441 if((ch>=‘0‘ && ch<=‘9‘) || ch==‘/‘ || ch==‘\‘‘){ 442 str += ch; 443 flag = true;//数没有压入栈中 444 }else{ 445 if(flag){ 446 try {//System.out.println(str); 447 Fraction f = new Fraction(str); 448 list.add(f); 449 flag = false; 450 str = ""; 451 } catch (Exception e) { 452 e.printStackTrace(); 453 } 454 455 } 456 457 } 458 i++; 459 }while(i < len); 460 int size = list.size(); 461 Fraction a[] = new Fraction[size]; 462 for( i = 0; i <size; i++) 463 a[i] = list.get(i); 464 return a; 465 } 466 public Equation precede()//取表达式中优先级最高的子表达式 467 { 468 try{ 469 //构建两个栈,分别存放分数和操作符 470 java.util.Stack<Fraction> mstack = new java.util.Stack<Fraction>(); 471 java.util.Stack<Character> ostack=new java.util.Stack<Character>(); 472 String express =new String( this.express); 473 boolean flag = false;//旗帜变量表示上一个分数是否压入了mStack栈中 474 express += "#"; 475 int i = 0,len = express.length(); 476 ostack.push(‘#‘); 477 String str = "";//中间字符串变量,用来读取表达式中的一个分数或者整数 478 479 while(i < len){ 480 char ch = express.charAt(i); 481 //当前字符为一个分数或者整数的一部分。 482 if((ch>=‘0‘ && ch<=‘9‘) || ch==‘/‘ || ch==‘\‘‘){ 483 str += ch; 484 flag = true;//数没有压入栈中 485 i++; 486 }else{//如果当前字符是空格或者操作符 487 if(flag){//如果上一个操作数还没有压入mStack栈,怎将其压入栈中 488 Fraction f=null; 489 try { 490 f = new Fraction(str); 491 } catch (Exception e) { 492 // TODO Auto-generated catch block 493 e.printStackTrace(); 494 f = new Fraction(1); 495 } 496 mstack.push(f); 497 str = ""; 498 flag = false;//数字已经压入栈中 499 } 500 if(ch == ‘ ‘)//如果当前字符是空格则跳过这个字符 501 i++; 502 else{//以下为运算过程 503 char op = ostack.peek(); 504 char tag = compare(op,ch); 505 switch(tag){ 506 507 case ‘<‘: 508 ostack.push(ch);i++;break; 509 case ‘>‘: 510 Fraction b = mstack.pop(); 511 Fraction a = mstack.pop(); 512 char oo = ostack.pop(); 513 Fraction c = calcul(a,oo,b); 514 String aa = a.toString(); 515 String bb = b.toString(); 516 String cc = c.toString(); 517 String newstr = aa+" "+oo+" "+bb; 518 Equation newexp = new Equation(newstr); 519 newexp.value =http://www.mamicode.com/ cc; 520 return newexp; 521 case ‘=‘: 522 ostack.pop(); 523 i++; 524 break; 525 } 526 } 527 528 } 529 } 530 }catch(Exception e){e.printStackTrace();} 531 return null; 532 } 533 }
实现分数运算的分数类:
1 public class Fraction { 2 3 public static void main(String[] args){ 4 try { 5 Fraction fraction = new Fraction("3/4"); 6 Fraction fraction2 = new Fraction("-2/5"); 7 Fraction fraction3 = new Fraction("0/1"); 8 System.out.println(fraction+" = "+fraction.doubleValue()); 9 System.out.println(fraction2+" = "+fraction2.doubleValue()); 10 System.out.print(fraction3+" = "+fraction3.doubleValue()); 11 } catch (Exception e) { 12 // TODO Auto-generated catch block 13 e.printStackTrace(); 14 } 15 } 16 17 private long numerator;//分子 18 private long denominator;//分母 19 20 public Fraction(String pattern) throws Exception{ 21 if(pattern.matches("[0-9]+‘[-]?[0-9]+/[0-9]+")){ 22 String[] s = pattern.split("[‘/]"); 23 int one = Integer.parseInt(s[0]); 24 int tow = Integer.parseInt(s[1]); 25 int three = Integer.parseInt(s[2]); 26 tow += one*three; 27 if(three==0) 28 throw new Exception("错误的表达式:"+pattern); 29 numerator = tow; 30 denominator = three; 31 this.yuefen(); 32 }else if(pattern.matches("[-]?[0-9]+/[0-9]+")){ 33 String[] s = pattern.split("/"); 34 int one = Integer.parseInt(s[0]); 35 int tow = Integer.parseInt(s[1]); 36 if(tow==0) 37 throw new Exception("错误的表达式:"+pattern); 38 numerator = one; 39 denominator=tow; 40 this.yuefen(); 41 }else if(pattern.matches("[-]?[0-9]+")){ 42 int one = Integer.parseInt(pattern); 43 numerator = one; 44 denominator=1; 45 }else{ 46 throw new Exception("不正确的表达式"+pattern); 47 } 48 } 49 public Fraction(long x1,long x2) throws Exception { 50 // TODO Auto-generated constructor stub 51 if(x2==0) 52 throw new Exception("denominator can‘t be 0!"); 53 if(x1<0&&x2<0) 54 { 55 x1 *= -1;x2 *= -1; 56 }else if(x2 <0&&x1>0){ 57 x1 *= -1;x2 *= -1; 58 } 59 this.numerator = x1; 60 this.denominator=x2; 61 this.yuefen(); 62 } 63 public Fraction(long x){ 64 this.numerator=x; 65 this.denominator=1; 66 } 67 public Fraction() { 68 this(1); 69 } 70 public Fraction(Fraction frac){ 71 this.numerator = frac.numerator; 72 this.denominator = frac.denominator; 73 } 74 75 public long getNumerator(){return numerator;} 76 public long getDenominator(){return denominator;} 77 public void setNumerator(long num){numerator=num;} 78 public void setDenominator(long deno){denominator=deno;} 79 80 81 private static long maxComDiv(long x1,long x2){//求两个数的最大公约数 82 long sum = 1; 83 long temp =x1<x2? x1:x2; 84 for(int i = 2; i <= temp;i++) 85 { 86 if(x1%i==0&&x2%i==0) 87 sum = i; 88 } 89 return sum; 90 } 91 private static long lcm(long x1,long x2){//求两个数的最小公倍数 92 return x1*x2/maxComDiv(x1, x2); 93 } 94 private void yuefen(){//约分 95 //求分子和分母的最大公约数 96 long x = Fraction.maxComDiv(this.numerator, this.denominator); 97 if(x != 1){ 98 //如果分子分母的最大公约数不是1,分子分母同时除以这个数 99 this.numerator/=x;this.denominator/=x; 100 } 101 } 102 private static void tongfen(Fraction x,Fraction y){//通分 103 104 if(x.denominator==y.denominator) 105 return ; 106 //求两个分母的最小公倍数m 107 long m = lcm(x.denominator,y.denominator); 108 x.numerator *= (m/x.denominator); 109 y.numerator *= (m/y.denominator); 110 x.denominator = m; 111 y.denominator = m; 112 } 113 114 public Fraction reciprocal() throws Exception{//求倒数 115 if(this.numerator==0) 116 throw new Exception("0没有倒数!"); 117 return new Fraction(this.denominator,this.numerator); 118 } 119 120 public Fraction multiply(Fraction another)//当前对象同另外一个分数相加返回一个新的分数 121 { 122 Fraction frac = null; 123 try{//对象在定义的时候已经有过分母为0的异常处理了, 124 //此处本来可以不用异常处理的,因为两个合法的分数相乘不可能出现分母为0 125 frac = new Fraction(numerator*another.numerator,denominator*another.denominator); 126 }catch(Exception e){} 127 frac.yuefen(); 128 return frac; 129 } 130 131 public Fraction divide(Fraction another) throws Exception//当前分数除以一分数,返回结果分数 132 { 133 //处理除数为0的异常情况 134 if(another.numerator==0) 135 throw new Exception("除数不能为0!"); 136 //求another的倒数 137 Fraction temp = another.reciprocal(); 138 //返回当前分数和another倒数的乘积 139 return multiply(temp); 140 141 } 142 143 public Fraction add(Fraction another)//分数相加 144 { 145 //如果两个分数的分母相同,直接分子相加 146 if(this.denominator==another.denominator) 147 try { 148 return new Fraction(this.numerator+another.numerator,this.denominator); 149 } catch (Exception e) { 150 } 151 //将当前分数this对象和another分别赋值给新的对象,因为分数加法需要通分 152 //新的对象通分后原来的对象不会改变。 153 Fraction x = new Fraction(this),y = new Fraction(another); 154 //新对象x,y通分得到两个分母相同的分数 155 tongfen(x,y); 156 //分母相同的分数分子相加 157 x.numerator+=y.numerator; 158 x.yuefen(); 159 return x; 160 } 161 162 public Fraction reduce(Fraction another)//分数相减 163 { 164 Fraction x =new Fraction(this); 165 //如果分母相同 166 if(x.denominator==another.denominator){ 167 x.numerator-=another.numerator; 168 x.yuefen(); 169 return x; 170 } 171 Fraction y = new Fraction(another); 172 tongfen(x,y); 173 x.numerator-=y.numerator; 174 x.yuefen(); 175 return x; 176 } 177 178 public Fraction multiply(int x)//分数和一个整数相乘 179 { 180 Fraction y = new Fraction(x); 181 return this.multiply(y); 182 } 183 184 public Fraction divide(int x) throws Exception//除以另一个分数 185 { 186 Fraction y = new Fraction(x); 187 return this.divide(y); 188 } 189 190 public Fraction add(int x)//分数和一个int类型的数相加 191 { 192 //将int类型数据转化为分数 193 Fraction y=new Fraction(x); 194 //调用分数加分数的方法得到结果 195 return this.add(y); 196 } 197 198 public Fraction reduce(int x)//分数减去一个整数 199 { 200 Fraction y = new Fraction(x); 201 return this.reduce(y); 202 } 203 204 public String toString()//将分数化为字符串用于输出 205 { 206 if(numerator > denominator&&denominator!=1){ 207 long t1 = numerator / denominator; 208 long t2 = numerator - t1*denominator; 209 return ""+t1+"‘"+t2+"/"+denominator; 210 } 211 if(this.numerator==0||this.denominator==1) 212 //当分子为0或者分母为1的时候直接输出分子 213 return ""+this.numerator; 214 else 215 return this.numerator+"/"+this.denominator; 216 } 217 218 public double doubleValue()//将分数化为浮点数 219 { 220 return (double)this.numerator/(double)this.denominator; 221 } 222 223 public int intValue(){ 224 return (int)(this.numerator/this.denominator); 225 } 226 227 public boolean lessThan(Fraction target)//比较当前分数和target的大小 228 { 229 Fraction x = new Fraction(this),y = new Fraction(target); 230 tongfen(x,y); 231 if(x.numerator < y.numerator) 232 return true; 233 else 234 return false; 235 } 236 public boolean equals(Fraction target)//判断相等 237 { 238 Fraction x = new Fraction(this),y = new Fraction(target); 239 if(x.numerator==y.numerator) 240 return true; 241 else 242 return false; 243 } 244 public boolean greaterThan(Fraction target) 245 { 246 Fraction x = new Fraction(this),y = new Fraction(target); 247 if(x.numerator>y.numerator) 248 return true; 249 else 250 return false; 251 } 252 }
运行结果截图
编程总结分析
PSP开发记录表
日期 |
开始时间 |
结束时间 |
中断时间 |
净时间 |
活动 |
2017/3/13 |
14:00 |
15:50 |
10minute |
100minute |
上课 |
2017/3/13 |
16:10 |
17:50 |
10minute |
100minute |
设计 |
2017/3/13 |
18:46 |
22:30 |
17minute |
223minute |
编程 |
2017/3/14 |
12:26 |
15:50 |
|
270minute |
编程 |
2017/3/14 |
16:10 |
17:40 |
|
90minute |
编程 |
2017/3/14 |
21:03 |
22:50 |
|
107minute |
复审 |
2017/3/15 |
12:35 |
14:50 |
|
135minute |
复审 |
2017/3/16 |
18:30 |
17:50 |
|
80minute |
整理写博客 |
四则运算三