Ответ 1
Это можно сделать следующим образом.
words = ["foo", "ofo", "goo"]
target = "foo"
target_size = target.size
#=> 3
target_sorted = target.each_char.sort
#=> ["f", "o", "o"]
words.select { |w| anagram?(target_size, target_sorted, w) }
#=> ["foo", "ofo"]
Типичный способ anagram?
записывается в следующем виде:
def anagram?(target_size, target_sorted, w)
return false unless w.size == target_size
w.each_char.sort == target_sorted
end
Однако я подумал, что может быть быстрее:
- Шаг через символы
target
- Найдите индекс
i
совпадающего символа вw
- Если совпадение найдено, удалите
w[i]
- Если совпадение не найдено (
i #=> nil
), вернитеfalse
- return
true
, еслиfalse
не возвращается ранее
Это можно реализовать таким образом:
def anagram?(target_size, target, w)
return false unless target.size == w.size
wcpy = w.dup
target.each_char do |c|
i = wcpy.index(c)
return false unless i
wcpy[i] = ''
end
true
end
words.select { |w| anagram?(target_size, target, w) }
#=> ["foo", "ofo"]
Мне нужно будет сравнить эти два дня.
[Изменить: Мы также можем написать:
def anagram?(w1, w2)
return false unless w1.size == w2.size
w1.chars.difference(w2.chars).empty?
end
Помощник Array#difference
определяется здесь.