2010-08-31 4 views
7

C'est un algorithme assez commun dans l'analyse de la ligne de commande. Étant donné un ensemble de noms d'options longs prédéfinis, calculez le préfixe le plus court qui identifie de façon unique l'une de ces options. Ainsi, par exemple, pour les options suivantes:Comment calculer les préfixes uniques les plus courts d'un ensemble de chaînes?

-help 
-hostname 
-portnumber 
-name 
-polymorphic 

Ce serait la sortie:

-he 
-ho 
-por 
-n 
-pol 

Je pense deux façons de le faire - soit comme un arbre:

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

ou en recherchant des sous-chaînes:

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; 
     } 
    } 
} 

Donc, la question est:

  1. Qui iriez-vous?
  2. Ai-je manqué une troisième voie évidente?
+0

Contexte, contexte, contexte! J'irais pour celui qui était meilleur dans mon scénario. –

+0

L'option 1 semble être la meilleure solution. Rapide, précis et direct ... – Kendrick

+0

Le contexte est l'analyse syntaxique en ligne de commande - il serait donc construit une fois et utilisé une seule fois. Comme il s'agit de garbage collection et que la plupart des systèmes d'exploitation limitent les lignes de commande à moins de 1 Mo, l'utilisation de la mémoire n'est pas un problème. Les performances doivent être équilibrées entre la construction de la structure et la consultation ultérieure, car les deux ne seront généralement effectuées qu'une seule fois. –

Répondre

5

La solution "arbre" est un cas particulier (enfin, c'est plutôt général) d'un Patricia trie.

Le premier sera généralement plus rapide à rechercher. Les considérations relatives à la mémoire ne sont probablement pas pertinentes dans votre contexte, car elles ne sont pas utilisées de façon permanente et vous ne faites qu'une seule fois la "recherche".

0

Je ferais l'arbre, ça a l'air bien.

Vous pouvez créer un hachage de toutes les sous-chaînes possibles.

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, oui, la réponse manquante la plus évidente est d'utiliser une bibliothèque qui le fait déjà. How to parse command line arguments in Java?

+0

Drôle, vous devriez dire que :) Je suis en train d'utiliser JCommander, mais il ne supporte pas cela, donc je pensais que je le suggérerais :) –

+0

Pour ce que ça vaut: Je crois que JCommander prend désormais en charge les arguments abrégés. – Zack

Questions connexes