Biorąc pod uwagę dwa ciągi, chciałbym określić, czy są one wzajemnie anagramami. Oto rozwiązanie, które wymyśliłem:Szybkie rozwiązywanie anagramów
# output messages
def anagram
puts "Anagram!"
exit
end
def not_anagram
puts "Not an anagram!"
exit
end
# main method
if __FILE__ == $0
# read two strings from the command line
first, second = gets.chomp, gets.chomp
# special case 1
not_anagram if first.length != second.length
# special case 2
anagram if first == second
# general case
# Two strings must have the exact same number of characters in the
# correct case to be anagrams.
# We can sort both strings and compare the results
if first.chars.sort.join == second.chars.sort.join
anagram
else
not_anagram
end
end
Ale myślę, że prawdopodobnie jest lepszy. I analizowano skuteczność tego rozwiązania, i wymyślił:
chars
: dzieli ciąg na tablicę znakówO(n)
sort
: sortuje ciąg alfabetycznie, nie wiem jaki rodzaj jest realizowany w Ruby, ale zakładaO(n log n)
ponieważ jest to ogólnie najlepiej znane sortowania wydajnośćjoin
: buduje ciąg z tablicy znakówO(n)
==
: porównanie ciąg sama będzie musiała zbadać każdy znak strun2*O(n)
Biorąc powyższe pod uwagę, że na kategorie wydajności całego rozwiązania jak O(n log n)
od sortowania miał najwyższą wydajność. Czy istnieje lepszy sposób na zrobienie tego, który jest bardziej wydajny niż O(n log n)
?
Przepraszam, chciałem wstawić 'n log n' Mam to w swoich notatkach, właśnie skopiowałem niewłaściwą formułę na pytanie. –
+1. Ściśle mówiąc, rozwiązaniem liczącym jest O (max (n, | alfabet |)).Rozmiar alfabetu jest technicznie stały, ale jeśli alfabet jest unicode, a struny są niemiśle, to będzie dominować. – rici
Rozwiązanie polegające na liczeniu, iterowanie za pomocą obu łańcuchów powoduje mieszanie każdego znaku i aktualizowanie jego liczby w miarę jej przechodzenia? Pomyślałem, że ten problem zawsze będzie "O (n)", ponieważ porównanie jest zawsze ograniczone przez całą długość łańcucha. –