2016-08-29 5 views
2

У меня есть письменный экзамен здесь, вот инструкция.Рубиновый ключ с использованием Split и Join

Напишите программу, которая печатает группы слов, которые являются анаграммами. Анаграммы - это слова, которые имеют одинаковые точные буквы в них, но в разных порядков. Ваш результат должен выглядеть примерно так:

["demo", "dome", "mode"] 
["neon", "none"] 

(и т.д.)

А вот решение для этого:

words = ['demo', 'none', 'tied', 'evil', 'dome', 'mode', 'live', 
      'fowl', 'veil', 'wolf', 'diet', 'vile', 'edit', 'tide', 
      'flow', 'neon'] 


result = {} 

words.each do |word| 
    key = word.split('').sort.join 
    if result.has_key?(key) 
    result[key].push(word) 
    else 
    result[key] = [word] 
    end 
end 

result.each do |k, v| 
    puts "------" 
    p v 
end 

Я пытался понять решение рубин кода, но не может легко понять его. Один из моих вопросов заключается в том, как вы можете проверить хэш-код result, если у него нет ключа или какого-либо элемента из него. Другое дело, как это сделать. join и. sort работает над этим кодом.

Я действительно смущаюсь, как все проходит через ответ. Может ли кто-нибудь там объяснить на этих кодах по строкам в непрофессионале, новичок, который является манекеном, как я, может понять?

+0

Добавление к хорошему объяснению с помощью @GaganGami: Даже если вы не использовали 'has_key?', Выражение 'result [key]' действительно, если ключ не существует. По умолчанию он просто возвращает 'nil' для отсутствующего ключа. Однако при создании хеша можно запросить другое значение по умолчанию. – user1934428

+0

Если вы нашли какой-либо из ответов, пожалуйста, выберите тот, который вам больше всего понравился. –

ответ

7

Я бы просто сделать это:

words = ['demo', 'none', 'tied', 'evil', 'dome', 'mode', 'live', 
     'fowl', 'veil', 'wolf', 'diet', 'vile', 'edit', 'tide', 
     'flow', 'neon'] 

words.group_by { |word| word.chars.sort }.values 

#=> [["demo","dome","mode"],["none","neon"],["tied","diet","edit","tide"],["evil","live","veil","vile"],["fowl","wolf","flow"]] 
+2

[Enumerable] (http://ruby-doc.org/core-2.3.1/Enumerable.html) действительно делает эту вещь очень простой. – tadman

+0

Можете ли вы объяснить свое решение в строгом соответствии с термином laymans, как манекен, как я, понял бы? –

+0

@tadman, это только делает его легким. Есть проблемы с эффективностью решения для более крупных наборов. –

2

поясню для вас код.

key = word.split('').sort.join 

Это создаст массив символов из строки, отсортирует буквы по алфавиту и затем присоединяет символы к новой строке. Таким образом, создается ключ для хеша.

Например, слово «режим» будет преобразовано в массив ['m', 'o', 'd', 'e'], чем отсортировано ['d', 'e', 'm', 'o'], поэтому окончательная строка ключа будет «демо». Таким образом, слова «режим» и «демонстрация» будут иметь один и тот же ключ в хэше.

if result.has_key?(key) 
    result[key].push(word) 
else 
    result[key] = [word] 
end 

Если ветка условия проверяет, имеет ли хэш заданный ключ, и если он добавляет это слово в массив. В противном случае он назначит массив только с ключевым словом.

+1

Здесь 'result = Hash.new {| h, k | h [k] = []} 'сэкономит много условной работы. Тогда вы можете просто 'result [key] << слово' – tadman