2013-04-18 14 views
6

Devo immagazzinare molte parole (+ 200k) in un programma Java e voglio accedervi molto velocemente. Ho solo bisogno di sapere se una parola data appartiene al mio "dizionario". Non ho bisogno di un paio come <word, smthg>. Se possibile, sto cercando una soluzione nella libreria standard.Java: Datastructure per l'archiviazione di molte parole

PS: Forse l'utilizzo di una struttura dati non è il modo migliore per farlo? Leggendo ogni volta il file contenente le parole sarà più efficiente?

modifica: è un piccolo progetto. Ho a che fare con l'efficacia e la memoria

Ultima modifica: Finalmente scelgo HashSet.

+2

Sembra un [HashSet] (http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html) potrebbe essere una buona idea. – Keppil

+0

Hai qualche idea sull'uso di [Lucene] (http://lucene.apache.org/) – SenthilPrabhu

+0

@Keppil Il problema in HashSet è che non è ordinato. Quindi la ricerca sarà più lenta. –

risposta

5

Usa set java perché i set sono strutture di dati ordinati lineari come TreeSet. Quindi per la ricerca, tecniche come la ricerca binaria possono essere implementate e sono veloci senza ripetizioni.

Questa è la struttura di un set java.

enter image description here

Inoltre non sarà intenzione di consentire la duplicazione di conseguenza riducendo la ridondanza e salverà la memoria.

Se si desidera conoscere vari algoritmi di ricerca, consultare questo collegamento. Ecco

http://bigocheatsheet.com/

+0

I set sprecheranno molta memoria. Esistono strutture dati specializzate per questo tipo di attività. –

+1

@IvayloStrandjev In media 200 parole di 10 caratteri, memorizzate in un HashSet, richiedono probabilmente da 5 a 10 MB di memoria. Questo non è molto ... – assylias

+3

Appena provato, è più vicino a 20 MB, ma non è ancora molto. – assylias

3

Utilizzare uno Trie o Patricia tree a seconda della distribuzione delle parole. Vorrei personalmente andare con Patricia tree in quanto è più ottimizzato per l'utilizzo della memoria (anche se è più difficile da implementare).

+5

Per una quantità piuttosto piccola di oggetti come nel caso d'uso dell'OP, un HashSet andrebbe benissimo.Vale anche la pena notare che non ci sono implementazioni di Trie/Patricia Tree nello standard JDK. – assylias

0

Forse volete testare le mie TrieMap o TrieSet implementazioni (found here)? Li ho scritti appositamente per casi come questo. Finora ho implementato Tries per le chiavi String e byte[].

TrieSet<String> t = Tries.newStringTrieSet(); 

    t.add("hello"); 
    t.add("help"); 
    t.add("hell"); 
    t.add("helmet"); 
    t.add("hemp"); 

    List<String> resultsA = new ArrayList<>(); 
    t.findElements("hel", true, resultsA); // search for prefix 

    List<String> resultsB = new ArrayList<>(); 
    t.findElements("ell", false, resultsB); // search for substring 

    System.out.println("A: " + resultsA); 
    System.out.println("B: " + resultsB); 

Ciò stampare:

A: [hell, hello, helmet, help] 
B: [hell, hello] 
+0

> 1,5 KLOC e non un singolo test? –

0

questo sguardo abbastanza ok per me, non so se ho sbagliato per qualche motivo:

//put all your words to an ArrayList and sort the list. 
List <String> arr = new Arraylist<>(); 
while(there is next) 
    arr.add(theWord) 
Collections.sort(arr); 

//this is your search method 
boolean mysearch(keyword){ 
    return Collections.binarySearch(arr, keyword) 
} 

La performance è: O(n*log_n) per inserimento dati e ricerca è O(log_n)

Diciamo che ogni stringa è 20B, sulla a verage. 20B *200000 = 4MB spazio.

Problemi correlati