簡體   English   中英

在一個大文件中找到兩個具有相同哈希碼的單詞-奇怪的輸出

[英]find two words with the same hash code in a large file - weird output

我試圖在Ubuntu 12.04的/usr/share/dict/words找到兩個具有相同哈希碼的/usr/share/dict/words

嘗試保留Map<Integer, HashSet<String>>

閱讀單詞后,計算其哈希碼h並將單詞放入鍵為h的集合中。

然后遍歷所有鍵並打印大小大於1的集合。

但是運行后我看到非常奇怪的輸出。

碼:

public static void main(String[] args) throws FileNotFoundException {
        HashSet<String> fileWords = new HashSet<>();
        Map<Integer, HashSet<String>> duplicats = new HashMap<>();
        Scanner scan = new Scanner(new File("/usr/share/dict/words"));

        while (scan.hasNext()) {
            String word = scan.nextLine();
            int h = word.hashCode();
            fileWords.add(word);
            duplicats.put(new Integer(h), fileWords);
        }

        Set<Integer> keySet = duplicats.keySet();
        for (Integer key : keySet) {
            HashSet<String> value = duplicats.get(key);
            if (value.size() > 1) {
                System.out.println(key + " : " + value.toString());
            }
        }
    }

輸出:

21917608 : [repaying, Zubenelgenubi, treason, indignation, eyetooth, ....// a lot of words

看起來很奇怪。 我不知道怎么了?

更新:

我找到了解決方案:

public static void main(String[] args) throws FileNotFoundException {
    Map<Integer, HashSet<String>> duplicats = new HashMap<>();
    Scanner scan = new Scanner(new File("/usr/share/dict/words"));

    while (scan.hasNext()) {
        String word = scan.nextLine();
        int h = word.hashCode();

        if (!duplicats.containsKey(h)) 
        {
            HashSet<String> newSet = new HashSet<>();
            newSet.add(word);
            duplicats.put(new Integer(h), newSet);
        } 
        else 
        {
            duplicats.get(h).add(word);
        }
    } /// rest the same

如何解決這個麻煩?

HashSet<String> fileWords = new HashSet<>();

您只需實例化一個集合,然后將所有單詞添加到其中。

您必須添加將執行以下操作的邏輯:

  1. 檢查您當前的哈希碼密鑰下是否已經有一個集合;
  2. 如果有,只需在其上添加單詞;
  3. 如果不是,請創建一個新集合,添加單詞,然后將其放入地圖中。

現在的方式是,將相同的集合放在所有地圖鍵下。

我不太了解您的代碼的用途,但是在duplicats您正在將每個hashCode映射到文件中所有String的集合( fileWords )。 然后顯示它。 以下代碼可以正常工作。

public static void main(String[] args) throws FileNotFoundException {

    Map<Integer,HashSet<String>> duplicats= new HashMap<Integer, HashSet<String>>() ;
    Scanner scan = new Scanner(new File("C:\\Downloads\\Software\\sourceforge.net\\souptonuts\\dictionary\\linuxwords.1\\linux.words"));

    while( scan.hasNext() ) {
        String word= scan.nextLine() ;
        int hc= new Integer( word.hashCode() ) ;
        HashSet<String> count= duplicats.get( hc ) ;
        if( count == null ) {
            count= new HashSet<String>() ;
            duplicats.put(hc, count ) ;
        }
        count.add( word );
    }

    int nonCollisionHashCodes= 0 ;
    int singleCollisionHashCodes= 0 ;
    int doubleCollisionHashCodes= 0 ;
    for(Entry<Integer, HashSet<String>> e : duplicats.entrySet() ) {
        if( e.getValue().size() <= 1 ) {
            nonCollisionHashCodes++;
        } else if( e.getValue().size() <= 2 ) {
            singleCollisionHashCodes++;
        } else if( e.getValue().size() <= 3 ) {
            doubleCollisionHashCodes++;
        } else {
            System.out.println(e.getKey() + " : " + e.getValue().size());
        }
    }
    System.out.println("Number of non-collision hashCodes: "+ nonCollisionHashCodes );
    System.out.println("Number of single-collision hashCodes: "+ singleCollisionHashCodes );
    System.out.println("Number of double-collision hashCodes: "+ doubleCollisionHashCodes );
}

至少對於我的字典,輸出為:

Number of non-collision hashCodes: 626167
Number of single-collision hashCodes: 885
Number of double-collision hashCodes: 6

請注意,沒有輸出超過雙沖突hashCodes。

以我的口味,這些統計數據相當不錯。 在字典中嘗試一下並發布結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM