2009-02-06 14 views
6

Come indicheresti le parole che sono anagrammi l'una dell'altra?Qual è un modo semplice per dire se un elenco di parole è un anagramma l'uno dell'altro?

Mi è stata fatta questa domanda quando ho fatto domanda per il mio attuale lavoro.

orchestra può essere riorganizzato in carthorse con tutte le lettere originali utilizzate esattamente una volta quindi le parole sono anagrammi l'una dell'altra.

+1

Hey! Facciamo questa domanda ad ogni programmatore che intervistiamo! Stai rovinando le cose per noi! –

+2

@Jim In Texas: la domanda non rovina la tua strategia di intervista, rivela che la strategia dell'intervista è fondamentalmente errata. Come scegliere un meccanico basato su quale tuta colore ha su. Perdere la conoscenza ai nuovi candidati che scegli sempre una tuta blu non rovina la tua strategia di raccolta meccanica. Lo rivela come la non-strategia come viziata dal fatto che possa essere infranta da persone senza alcuna conoscenza della programmazione. –

+0

Trovo difficile immaginare "le persone che non conoscono la programmazione" siano in grado di stare in piedi davanti a una lavagna bianca e scrivere un programma per rilevare gli anagrammi. Questa è davvero una grande domanda iniziale sullo schermo per molte ragioni. E davvero, se un candidato è interessato abbastanza da aver letto questa domanda SO, allora questa è una buona cosa! –

risposta

22

Inserire tutte le lettere in ordine alfabetico nella stringa (algoritmo di ordinamento) e quindi confrontare la stringa risultante.

-Adam

+1

Sì, è più o meno quello che mi è venuto in mente ... Ho ottenuto anche il lavoro! – jqs

+0

C'è un algoritmo alternativo che coinvolge il conteggio dei caratteri in ogni parola. È più veloce, ma sarà più costoso per le parole Unicode. –

+0

L'avevo preso in considerazione, ma poi devi confrontare gli array di conteggio delle lettere risultanti, gli hash, o altrimenti - per gli anagrammi corti il ​​mio algoritmo è probabilmente più veloce, ma per le anagrammi più grandi le probabilità sono buone le tue sarebbero più veloci. Sarebbe un test interessante ... –

6

Ordina ogni elemento (rimuovendo gli spazi) e confrontalo con il precedente. Se sono tutti uguali, sono tutti anagrammi.

+0

Rimuovi anche la punteggiatura – dmckee

+0

punteggiatura Posso capire, per parole con un apostrohphe, ma spazi? Non conosco molte parole con spazi in esse ... Penso che per un semplice esercizio come questo puoi tranquillamente pensare che le parole contengano solo lettere. – ninesided

+0

Quando vengono presentati come puzzle, gli anagrammi sono spesso distribuiti su intere frasi. Quindi scrivi la routine per essere robusta. – dmckee

1

Ordina le lettere e confrontare (lettera per lettera, stringa di confronto, ...) è la prima cosa che viene in mente.

2

Il seguente algoritmo dovrebbe funzionare:

  1. Ordinare le lettere di ogni parola.

  2. Ordinare gli elenchi ordinati di lettere in ciascuna lista.

  3. Confrontare ogni elemento in ciascuna lista per l'uguaglianza.

+0

Una volta ordinati gli elenchi di lettere, è possibile confrontare il primo all'ultimo anziché confrontarlo. Se il primo è uguale all'altro, allora sono tutti uguali. –

+0

@EricNess Ne sei sicuro? Considera l'input: "abbc" e "abcc". Stessa lunghezza, stesso primo e ultimo carattere ... O forse ho frainteso il tuo commento. – levigroker

10

Buona cosa viviamo tutti nella realtà C# di ordinamento sul posto di parole brevi su macchine quad core con oozles di memoria. :-)

Tuttavia, se ti capita di essere vincolato dalla memoria e non puoi toccare i dati originali e sai che quelle parole contengono caratteri dalla metà inferiore della tabella ASCII, potresti scegliere un algoritmo diverso che conta l'occorrenza di ogni lettera in ogni parola invece di ordinare.

Si potrebbe anche optare per quell'algoritmo se si vuole farlo in O (N) e non si preoccupa dell'utilizzo della memoria (un contatore per ogni char Unicode può essere piuttosto costoso).

0
  1. confrontare la lunghezza (se non uguale, non una possibilità)
  2. fare un po 'di vettore della lunghezza delle stringhe
  3. per ogni char nella prima stringa di trovare occorrenze nel secondo
  4. impostare il bit per la prima occorrenza unset
  5. se si può trovare una fermata con fallire
2

Bene ordinare le parole della lista.

se abc, bca, cab, cba sono gli ingressi, quindi la lista ordinata sarà abc, abc, abc, abc.

Ora tutti i loro codici Hash sono uguali.Confronta i codici hash.

0
public static void main(String[] args) { 

    String s= "abc"; 
    String s1="cba"; 



    char[] aArr = s.toLowerCase().toCharArray(); 
    char[] bArr = s1.toLowerCase().toCharArray(); 

    // An array to hold the number of occurrences of each character 
    int[] counts = new int[26]; 

    for (int i = 0; i < aArr.length; i++){ 
    counts[aArr[i]-97]++; // Increment the count of the character at respective position 
    counts[bArr[i]-97]--; // Decrement the count of the character at respective position 
    } 

    // If the strings are anagrams, then counts array will be full of zeros not otherwise 
    for (int i = 0; i<26; i++){ 
    if (counts[i] != 0) 
    return false; 
    } 
0

logica hashcode provato per anagramma mi dà falsa uscita

public static Boolean anagramLogic(String s,String s2){ 
    char[] ch1 = s.toLowerCase().toCharArray(); 
     Arrays.sort(ch1); 
     char[] ch2= s2.toLowerCase().toCharArray(); 
     Arrays.sort(ch2); 
     return ch1.toString().hashCode()==ch2.toString().hashCode(); //wrong 
    } 

per rettificare questo codice, sotto è l'unica opzione che vedo, apprezzare tutte le raccomandazioni

char[] ch1 = s.toLowerCase().toCharArray(); 
     Arrays.sort(ch1); 
     char[] ch2= s2.toLowerCase().toCharArray(); 
     Arrays.sort(ch2); 
     return Arrays.equals(ch1,ch2); 
    } 
Problemi correlati