2015-01-12 26 views
1

我正在編寫一個簡單的程序如下:給定兩個數字M和N,p來自[M,N],q來自[1,p-1],找到所有不可縮減的部分p/q。 我的想法是蠻力p,q的所有可能的價值。並使用HashSet來避免重複的部分。但是,包含函數不能按預期工作。Java HashSet包含不起作用的函數

我的代碼

import java.util.HashSet; 
import java.util.Set; 

public class Fraction { 
    private int p; 
    private int q; 

    Fraction(int p, int q) { 
     this.p = p; 
     this.q = q; 
    } 

    public static int getGCD(int a, int b) { 
     if (b == 0) 
      return a; 
     else 
      return getGCD(b, a % b); 
    } 

    public static Fraction reduce(Fraction f) { 
     int c = getGCD(f.p, f.q); 
     return new Fraction(f.p/c, f.q/c); 
    } 

    public static HashSet<Fraction> getAll(int m, int n) { 
     HashSet<Fraction> res = new HashSet<Fraction>(); 
     for (int p = m; p <= n; p++) 
      for (int q = 1; q < p; q++) { 
       Fraction f = new Fraction(p,q); 
       Fraction fr = reduce(f); 
       if (!res.contains(fr)) 
        res.add(fr); 
      } 
     return res; 
    } 

    public static void print(Fraction f) { 
     System.out.println(f.p + "/" + f.q); 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     HashSet<Fraction> res = getAll(2, 4); 
     for (Fraction f : res) 
      print(f); 
    } 

} 

以下是節目

的輸出
4/3 
3/1 
4/1 
2/1 
3/2 
2/1 

你可以看到分數2/1是重複的。任何人都可以幫助我找出爲什麼以及如何解決它。 非常感謝。

回答

4

覆蓋Fraction#equalsFraction#hashCode。這些內部用於確定兩個對象是否相同。我想當你不覆蓋它們時,equals方法測試對象的地址是否相等,而不是它們的內部表示。

@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + p; 
    result = prime * result + q; 
    return result; 
} 

@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    Fraction other = (Fraction) obj; 
    if (p != other.p) 
     return false; 
    if (q != other.q) 
     return false; 
    return true; 
} 
3

您需要執行Fraction#equals()Fraction#hashcode(),因爲這是用於確定天氣的集合是否包含某個值。沒有它,比較對象引用,這不會給你想要的結果。

+2

讓我們不要忘了'的hashCode()'方法以及:哪些問題應該在Java中覆蓋equals和hashCode時,應考慮?](HTTP://計算器.COM /問題/ 27581 /乜問題,應待考慮-時,壓倒一切的,等於和 - 哈希碼功能於JAVA) – Pshemo

0

Fraction類沒有重載hashCodeequals。 A HashMap包含嘗試使用與您提供的hashCode(和equals)相同的密鑰來查找密鑰。在創建Fraction的新實例時,它將永遠不會與HashMap中的實例相同。這裏是你會怎麼做hashCodeequals

@Override 
public int hashCode() { 
    return super.hashCode() + p * 24 + q * 24; 
} 

@Override 
public boolean equals(Object other) { 
    if (!(other instanceof Fraction)) return false; 
    return ((Fraction) other).p == this.p && ((Fraction) other).q == this.q; 
}