Per quanto riguarda l'esempio nel tutorial online java di Oracle che utilizza HashMap per memorizzare l'anagramma


Stavo leggendo l'esempio nel tutorial java online di Oracle che utilizza HashMap per memorizzare anagrammi:

    // Read words from file and put into a simulated multimap
    Map<String, List<String>> m = new HashMap<String, List<String>>();

    try {
        Scanner s = new Scanner(new File(args[0]));
        while (s.hasNext()) {
            String word = s.next();
            String alpha = alphabetize(word);
            List<String> l = m.get(alpha);
            if (l == null)
                m.put(alpha, l=new ArrayList<String>());
            l.add(word);
        }
    } catch (IOException e) {
        System.err.println(e);
        System.exit(1);
    }

    // Print all permutation groups above size threshold
    for (List<String> l : m.values())
        if (l.size() >= minGroupSize)
            System.out.println(l.size() + ": " + l);
}

private static String alphabetize(String s) {
    char[] a = s.toCharArray();
    Arrays.sort(a);
    return new String(a);
}

}

Poiché HashMap è implementato con Hash Table, penso che ogni stringa alfabetizzata ordinata dovrebbe avere un codice hash univoco dopo la compressione(altrimenti l'elenco collegato che memorizza i valori nell'HashMap memorizzerà un valore che non è un anagramma della stringa alfabetizzata ordinata).

Non sono esattamente sicuro di come l'implementazione di Java HashMap può soddisfare questo-presumo che usino il codice hash di una stringa (a1*31^n-1 + a2*31^n-2 + ... + un). Ciò potrebbe garantire l'unicità del codice hash se stiamo parlando di stringhe con solo caratteri minuscoli. Tuttavia, si deve anche comprimere il codice hash prima di inserire il valore della chiave nel bucket nella tabella hash (altrimenti si avrebbe una tabella hash hugggggge che non può essere gestita in memoria, solo pensando a quanto è grande 31^10). Tra questa compressione, penserei che ci sarà collisione. In altre parole, due stringhe diverse che non sono veri anagrammi finiranno per essere memorizzate nello stesso bucket (che dovrebbe essere usato solo per memorizzare un elenco di veri anagrammi)...

Qualcuno potrebbe aiutarmi a capire cosa potrei perdere? O se il tutorial online manca qualcosa?

Grazie!

Giasone

Author: Eric H., 2012-11-26

1 answers

Mai, mai presumere che i codici hash siano unici, ma rendersi conto che HashMap sa già che i codici hash non sono univoci e li tratta in modo appropriato.

In altre parole, anche se a.hashCode() == b.hashCode(), se !a.equals(b), allora un HashMap non mescolerà il valore associato a a e il valore associato a b.

 1
Author: Louis Wasserman, 2012-11-26 21:08:46