2015-11-08 72 views
2

我有兩個類:分數和測試。我已經和Class Fraction做得很好,但Test類有一些問題。問題與比較兩個分數

我想讓用戶輸入分數並存儲在ArrayList中,用戶可以通過選擇數組的索引來比較數組中的兩個分數。但是當我比較兩個分數時,它不能很好地工作!

類分數:

class Fraction { 

    private int numerator; 
    private int denominator; 

    Fraction(int n, int d) { 
     numerator = n; 
     denominator = d; 
    } 

    public Fraction(int n) { 
     this(n, 1); 
    } 

    public Fraction() { 
     numerator = 0; 
     denominator = 1; 
    } 

    public int getNumerator() { 
     return numerator; 
    } 

    public void setNumerator(int numerator) { 
     this.numerator = numerator; 
    } 

    public int getDenominator() { 
     return denominator; 
    } 

    public void setDenominator(int denominator) { 
     this.denominator = denominator; 
    } 

    public void display() { 
     String s = this.getNumerator() + "/" + this.getDenominator(); 
     System.out.println(s); 
    } 

    public double evaluate() { 
     double n = numerator; 
     double d = denominator; 
     return (n/d); 
    } 

    public boolean isEquals(Fraction f){ 
     int gcd1 = gcd(f.getNumerator(), f.getDenominator()); 
     double fractionFloatValue = (f.getNumerator()/gcd1)/(f.getDenominator()/gcd1); 
     int gcd2 = gcd(this.getNumerator(), this.getDenominator()); 
     double fractionFloatValue2 = (this.getNumerator()/gcd2)/(this.getDenominator()/gcd2); 
     return (fractionFloatValue == fractionFloatValue2) ? true : false; 

    } 

    public Fraction add(Fraction f2) { 
     Fraction r = new Fraction((numerator * f2.denominator) 
       + (f2.numerator * denominator), (denominator * f2.denominator)); 
     return r; 
    } 

    static private int gcd(int x, int y) { 
     return y == 0 ? x : gcd(y, x % y); 
    } 

    public static String asFraction(int x, int y) { 
     int gcd = gcd(x, y); 
     return (x/gcd) + "/" + (y/gcd); 
    } 

    /*public static void main(String[] argv) { 

     Fraction f0 = new Fraction(); 
     Fraction f1 = new Fraction(3); 
     Fraction f2 = new Fraction(20, 60); 
     Fraction f3 = new Fraction(1, 3); 

     System.out.println("--------------Testing constructors--------------"); 
     f0.display(); 
     f1.display(); 
     f2.display(); 
     System.out.println("--------------Test if two fractions is equal--------------"); 
     System.out.println(f2.isEquals(f1)); 
    }*/ 
} 

和類測試:

import java.util.ArrayList; 
import java.util.Scanner; 

public class Test { 

    public static void enterFraction(){ 
     ArrayList<Fraction> arr = new ArrayList<Fraction>(); 
     Scanner scanner = new Scanner(System.in); 
     boolean check = false; 
     int i = 1; 
     while(!check){ 
      System.out.println("Enter fraction"+i+":"); 
      Fraction f = new Fraction(); 
      System.out.println("Enter Numerator: "); 
      int numerator = scanner.nextInt(); 
      scanner.nextLine(); 
      f.setNumerator(numerator); 
      System.out.println("Enter Denominator: "); 
      int denominator = scanner.nextInt(); 
      scanner.nextLine(); 
      f.setDenominator(denominator); 
      System.out.println("Your fraction"+i+" is: "+f.getNumerator()+"/"+f.getDenominator()); 
      arr.add(f); 
      System.out.println("Want to compare fractions? (Y/Yes or N/No)"); 
      String compareRequest = scanner.nextLine(); 
      if(compareRequest.equalsIgnoreCase("y")){ 
       System.out.println("Choose your target fraction!!! (enter the index of the array)"); 
       int position = scanner.nextInt(); 
       scanner.nextLine(); 
       Fraction targetFraction = arr.get(position); 
       targetFraction.display(); 
       System.out.println("Choose your second fraction to compare!!! (enter the index of the array)"); 
       int position2 = scanner.nextInt(); 
       scanner.nextLine(); 
       Fraction secondFraction = arr.get(position2); 
       secondFraction.display(); 
       boolean compareTwoFractions = secondFraction.isEquals(targetFraction); 
       if(compareTwoFractions == true){ 
        System.out.println("Two fractions are equal"); 
       } 
       else if(compareTwoFractions == false){ 
        System.out.println("Two fractions are not equal"); 
       }   
      } 
      i++; 
      System.out.println("Do you want to enter more fraction? (Y/Yes or N/No)"); 
      String checkRequest = scanner.nextLine(); 
      if(checkRequest.equalsIgnoreCase("n")){ 
       check = true; 
      } 
     } 
    } 

    public static void main(String[] args){ 
     enterFraction(); 
    } 
} 

我輸入這樣的:

Enter fraction1: 
Enter Numerator: 
2 
Enter Denominator: 
4 
Your fraction1 is: 2/4 
Want to compare fractions? (Y/Yes or N/No) 
n 
Do you want to enter more fraction? (Y/Yes or N/No) 
y 
Enter fraction2: 
Enter Numerator: 
1 
Enter Denominator: 
3 
Your fraction2 is: 1/3 
Want to compare fractions? (Y/Yes or N/No) 
y 
Choose your target fraction!!! (enter the index of the array) 
0 
2/4 
Choose your second fraction to compare!!! (enter the index of the array) 
1 
1/3 
Two fractions are equal 
Do you want to enter more fraction? (Y/Yes or N/No) 

你看它不行,2/4 == 1/3。請用這個指點我。

+1

你看到我的類分數,我比較f2和f1,它返回false,但是當我嵌入類Test中,它不會像這樣工作。 – Khuong

+0

不相關但是,在你的'isEquals'方法中,因爲你所做的只是測試分數的十進制值,所以不需要計算gcd。只需檢查'getNumerator()/ getDenominator()'它應該返回相同的值。也就是說,如果你不使用dasblinkenlights中的身份概念,那麼回答是 – pinkfloydx33

回答

3

問題是,getNumerator(),getDenominator()gcd返回int。因此,您的equals方法內部分工在整數做:

double fractionFloatValue = (f.getNumerator()/gcd1)/(f.getDenominator()/gcd1); 
... 
double fractionFloatValue2 = (this.getNumerator()/gcd2)/(this.getDenominator()/gcd2); 

fractionFloatValuefractionFloatValue2的價值,實際上,整數,即使他們被分配到double類型的變量。 1/31/2都是正確的分數,因此在這兩種情況下整數除法都爲零。這就是爲什麼在這兩種情況下你的equals返回true

有兩種方法來解決這個問題:

  • 申報gcd1gcd2double。這將迫使劃分爲double;不幸的是,你的代碼將遭受雙重比較的平等,這本質上是不精確的,或
  • 使用身份n1/d1 == n2/d2n1*d2 == n2*d1。這消除了分割,因此在比較中可以獲得完美的精度,直到溢出爲止(如果對乘法結果使用long,則不會溢出使用的約束條件)。
+1

是的,我通過添加* 1.0來解決它 – Khuong

1

我改變雙線是@dasblinkenlight已經提到:

double fractionFloatValue = ((f.getNumerator()/gcd1)*1.0)/(f.getDenominator()/gcd1); 

double fractionFloatValue2 = ((this.getNumerator()/gcd2)*1.0)/(this.getDenominator()/gcd2); 

和現在的工作。