Ruby anagram solver [закрыто]
Я хочу написать решатель типа анаграммы в Ruby, но он будет работать со списком слов, например.
список слов:
the
these
one
owner
Я бы позволил пользователю ввести некоторые буквы, e.G noe, и он будет искать в списке слов слова, которые он может сделать, используя буквы, введенные пользователем, и вернет one и если они войдут в " eth "или даже" the", это вернет the. Я пытаюсь придумать эффективный способ сделать это, но я обводил вокруг каждого слова, соответствовал букве в слове, проверяя слово для каждой буквы, и обе длины совпадают. Может ли кто-нибудь дать совет лучшего и более эффективного способа сделать это?
7 ответов
большая идея заключается в том, что все анаграммы идентичны при сортировке. Поэтому, если вы создадите хэш (не знаю, что Ruby называет это) списков, где ключи сортируются словами, а значение-это список слов, которые сортируются по данному ключу, то вы можете найти анаграммы очень быстро, сортируя Слово и глядя в свой хэш.
ответ rrenaud велик, и вот пример того, как построить такой хэш в ruby, учитывая массив с именем "words", который содержит все слова в своем словаре:
@words_hash = words.each_with_object(Hash.new []) do |word, hash|
hash[word.chars.sort] += [word]
end
код выше предполагает ruby 1.9.2. Если вы используете более старую версию, то chars не существует, но вы можете использовать .split('').sort.
объектом по умолчанию хэша является пустой массив, что облегчает кодирование в некоторых случаях, потому что вам не нужно беспокоиться о гашиш дает тебе ноль.
источник:https://github.com/DavidEGrayson/anagram/blob/master/david.rb
одним из решений может быть:
def combine_anagrams(words)
output_array = Array.new(0)
words.each do |w1|
temp_array = []
words.each do |w2|
if (w2.downcase.split(//).sort == w1.downcase.split(//).sort)
temp_array.push(w2)
end
end
output_array.push(temp_array)
end
return output_array.uniq
end
Я не мог устоять перед решением этой ruby quiz:)
class String
def permutation(&block)
arr = split(//)
arr.permutation { |i| yield i.join }
end
end
wordlist = ["one", "two"]
"noe".permutation do |i|
puts "match found: #{i}" if wordlist.include?(i)
end
основная идея заключается в том, что он создает и массив и использует его функцию перестановки, чтобы придумать результат. Это может быть не эффективно, но я нахожу это элегантным. : D
Это может быть то, что вы ищете: Решение Анаграмм В Ruby
вот еще один подход (это лучший ответ): Анаграмма Решатель В Python
def combine_anagrams(words)
cp = 0
hash = Hash.new []
words.each do |word|
cp += 1
(cp..words.count).each do |i|
hash[word.to_s.chars.sort.join] += [word]
end
hash[word.to_s.chars.sort.join] = hash[word.to_s.chars.sort.join].uniq
end
return hash
end
вот довольно похожий на мой. Чтение из файла словаря и сравнение отсортированных символов в виде массива. Сортировка производится по заранее выбранным кандидатам.
def anagrams(n)
text = File.open('dict.txt').read
candidates = []
text.each_line do |line|
if (line.length - 1) == n.length
candidates << line.gsub("\n",'')
end
end
result = []
candidates.each do |word|
if word.chars.sort == n.chars.sort
result << word
end
end
result
end