2009-02-06 7 views
6

W jaki sposób wymieniasz słowa, które są wzajemnie anagramami?Co to jest łatwy sposób stwierdzić, czy lista słów jest wzajemnie anagramowa?

Zostałem poproszony o to pytanie, gdy ubiegałem się o moją obecną pracę.

może być zmieniony na carthorse z wszystkimi oryginalnymi literami używanymi dokładnie jeden raz dlatego słowa są anagramami od siebie.

+1

Hej! Zadajemy to pytanie każdemu programiście, z którym przeprowadzamy wywiad! Zepsujesz dla nas rzeczy! –

+2

@ Jim W Teksasie: pytanie nie psuje twojej strategii wywiadu, ujawnia strategię rozmowy kwalifikacyjnej, która ma fundamentalne wady. Jak wybieranie mechanika na podstawie tego, jakie kombinezony ma na sobie. Wyciek wiedzy dla nowych kandydatów, którzy zawsze wybierają niebieskie kombinezony, nie psuje twojej strategii mechanicznego kompletowania. Uznaje to za nie-strategię za wadliwą, ponieważ może zostać złamana przez ludzi bez znajomości programowania. –

+0

Trudno mi sobie wyobrazić, że ludzie, którzy nie znają programowania, mogą stanąć na białej tablicy i napisać program do wykrywania anagramów. Jest to naprawdę świetne pytanie początkowe z wielu powodów. I rzeczywiście, jeśli kandydat jest wystarczająco zainteresowany, aby przeczytać to pytanie, to dobrze! –

Odpowiedz

22

Umieść wszystkie litery w kolejności alfabetycznej w ciągu znaków (algorytm sortowania), a następnie porównaj wynikowy ciąg.

-Adam

+1

Tak, to jest to, co wymyśliłem ... Mam też pracę! – jqs

+0

Istnieje alternatywny algorytm polegający na zliczaniu znaków w każdym słowie. Jest szybszy, ale będzie droższe dla słów Unicode. –

+0

Rozważałem to, ale potem musisz porównać wynikowe tablice z liczbami, hashe, lub inaczej - dla krótkich anagramów mój algorytm jest prawdopodobnie szybszy, ale dla większych anagramów szanse są dobre, twoje będzie szybsze. Byłby to ciekawy test ... –

6

Sortowanie każdego elementu (usuwanie białych znaków) i porównywanie z poprzednim. Jeśli wszystkie są takie same, wszystkie są anagramami.

+0

Usunięcie interpunkcji oraz interpunkcji – dmckee

+0

Mogę zrozumieć, jeśli chodzi o słowa z apostrohphe, ale spacje? Nie znam wielu słów, w których są spacje ... Myślę, że w celu wykonania prostego ćwiczenia można bezpiecznie założyć, że słowa zawierają tylko litery. – ninesided

+0

Prezentowane jako układanki anagramy są często rozłożone na całe frazy. Więc piszesz rutynę, aby być solidnym. – dmckee

1

Sortuj litery i porównać (litera po literze, ciąg porównania, ...) to pierwsze rzeczy, które przychodzi do głowy.

2

Poniższy algorytm powinien działać:

  1. posortować litery każdego słowa.

  2. Posortuj posortowane listy liter na każdej liście.

  3. Porównaj każdy element na każdej liście pod kątem równości.

+0

Po posortowaniu listy liter można porównać pierwsze do ostatniego, zamiast porównywać poszczególne. Jeśli pierwszy jest taki sam jak ostatni, wszystkie są równe. –

+0

@EricNess Czy jesteś tego pewien? Rozważ wejście: "abbc" i "abcc". Ta sama długość, te same pierwsze i ostatnie postacie ... A może źle zrozumiałem twój komentarz. – levigroker

10

Dobrze, że wszyscy żyjemy w rzeczywistości C# w miejscu sortowania krótkich słów na maszynach czterordzeniowych z jazami pamięci. :-)

Jeśli jednak masz ograniczoną pamięć i nie możesz dotknąć oryginalnych danych i wiesz, że te słowa zawierają znaki z dolnej połowy tabeli ASCII, możesz wybrać inny algorytm, który się liczy występowanie każdej litery w każdym słowie zamiast sortowania.

Możesz także wybrać ten algorytm, jeśli chcesz zrobić to w trybie O (N) i nie obchodzi go użycie pamięci (licznik każdego znaku Unicode może być dość kosztowny).

0
  1. porównać długość (jeśli nie równy, a nie przypadkowo)
  2. dokonać bitowy wektor długości strun
  3. dla każdego char w pierwszym ciągiem znaleźć wystąpienia niego w drugim
  4. ustawić bit dla pierwszego wyłączonym wystąpienia
  5. jeśli można znaleźć jeden przystanek z funkcją
2

Dobrze Sortowanie słów na liście.

jeśli abc, bca, cab, cba są wejściami, to posortowana lista będzie abc, abc, abc, abc.

Teraz wszystkie ich kody są równe.Porównaj HashCodes.

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

Tried logika hashcode dla anagram daje mi fałszywe wyjście

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 
    } 

naprawić ten kod, poniżej jest jedyną opcją, widzę, doceniam wszelkie zalecenia

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