2010-08-31 4 views
7

È un algoritmo piuttosto comune nella riga di comando che analizza. Dato un insieme di nomi di opzioni lunghi predefiniti - calcola il prefisso più breve che identifica in modo univoco una di queste opzioni. Così, per esempio, per le seguenti opzioni:Come calcolare i prefissi unici più brevi di un set di stringhe?

-help 
-hostname 
-portnumber 
-name 
-polymorphic 

Questo sarebbe l'output:

-he 
-ho 
-por 
-n 
-pol 

sto pensando due possibili modi per farlo - sia come un albero:

   * 
      /| \ 
      /| \ 
      H N P 
     /\  | 
     E O  O 
       /\ 
       R L 

O la ricerca di stringhe:

for (String s : strings) { 
    for (int i = 1; i < s.length(); s++) { 
     if (search(strings,s.substring(0,i)) == 1) { 
      result.add(s.substring(0,i); 
      break; 
     } 
    } 
} 

Quindi, la domanda è:

  1. Quale sceglieresti?
  2. Mi manca un'ovvia terza via?
+0

Contesto, contesto, contesto! Vorrei andare per quello che era meglio nel mio scenario. –

+0

L'opzione 1 sembra il modo migliore per andare. Veloce, preciso e diretto ... – Kendrick

+0

Il contesto è l'analisi della riga di comando, quindi sarebbe costruito una sola volta e utilizzato una sola volta. Dal momento che questo è garbage collection e la maggior parte dei sistemi operativi limita le righe di comando in meno di 1 MB l'utilizzo della memoria non è un problema. Le prestazioni devono essere bilanciate tra la costruzione della struttura e la successiva ricerca, poiché entrambe, in generale, verranno eseguite una sola volta. –

risposta

5

La soluzione "albero" è un caso particolare (beh, in realtà è abbastanza generale) di un Patricia trie.

Il primo sarà generalmente più veloce da cercare. Le considerazioni sulla memoria probabilmente non sono rilevanti per il tuo contesto, dal momento che non vengono utilizzate in modo permanente e stai eseguendo la "ricerca" una sola volta.

0

Farei l'albero, sembra buono.

È possibile creare un hash di ogni sottostringa distinta possibile.

Hashmap<String, String> validSubs = new Hashmap<String, String>(); 
HashSet<String> usedSubs = new HashSet<String>(); 

for (String option : options) { 
    for(int i = 0; i <= option.length; i++) { 
    String sub = option.substring(0, i); 
    if(usedSubs.contains(sub)) { 
     validSubs.remove(sub); 
    } else { 
     validSubs.add(sub, option); 
     usedSubs.add(sub); 
    } 
    } 
} 
0

Oh, sì, la risposta mancante più ovvia è usare una libreria che già lo fa. How to parse command line arguments in Java?

+0

Divertente dovresti dire che :) In realtà sto usando JCommander, ma non supporta questo quindi ho pensato di suggerirlo :) –

+0

Per quello che vale: Credo che JCommander ora supporti argomenti abbreviati. – Zack

Problemi correlati