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