首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby - Anagram码

Ruby - Anagram码
EN

Stack Overflow用户
提问于 2016-10-05 09:04:37
回答 3查看 2.5K关注 0票数 6

我们这里有很多词:

代码语言:javascript
复制
words =  ['demo', 'none', 'tied', 'evil', 'dome', 'mode', 'live',
          'fowl', 'veil', 'wolf', 'diet', 'vile', 'edit', 'tide',
          'flow', 'neon']

我的老师写了一个程序,打印出一组字谜。字谜是指单词中有相同的确切字母,但顺序不同。输出应该如下所示:

代码语言:javascript
复制
["demo", "dome", "mode"]
["neon", "none"]
(etc)

这是我老师给我们看的解决方案:

代码语言:javascript
复制
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[key].push(word),以及它上面写的result[key] = [word],我知道这可能是一个没有问题的问题,但是那里的任何人都可以用一个外行的术语或者一个像我这样的虚拟人的方式逐行解释解决方案。

PS。不好意思新手来了。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-05 09:46:02

请参见内联注释:

代码语言:javascript
复制
words.each do |word| #=>  iterate each word in words array. "word" variable will have value at a particular iteration
  key = word
  .split('') #=> splits word, if word is 'demo' on iteration then it will be: `['d', 'e', 'm', 'o']`
  .sort #=> sorts the splitted array, i.e. the array above will be: `['e', 'd', 'm', 'o']`
  .join #=> joins the array sorted in above operation, it will be: 'edmo'. Since this is last operation, it will be returned and saved in `key` variable
  if result.has_key?(key) #=> Check whether result(Hash) already has key: `edmo`, returns true if present
    result[key].push(word) #=> result['edmo'] will give an array value, which can push word in that array
  else #=> false when key is not present in result Hash.
    result[key] = [word] #=> then add key with an array such as: `result['edmo] = ['demo']`
  end
end

然而,你也可以用惯用的方式做同样的事情:

代码语言:javascript
复制
result = Hash.new{|h, k| h[k] =[] } #=> if key does not exist then the default value will be an array.

因此,上述代码将成为:

代码语言:javascript
复制
words.each do |word|
  key = word.split('').sort.join
  result[key] << word # no need to validate whether we have key in Hash or not
end

但是,这种将值保持为数组的方法存在一个问题。如果我们的单词数组中有重复的单词,那么您的键中就会有重复的数据。只需将数组更改为设置即可解决问题:

代码语言:javascript
复制
require 'set'
result = Hash.new{|h, k| h[k] = Set.new }

现在,我们都很好。

票数 4
EN

Stack Overflow用户

发布于 2016-10-05 09:09:10

它基本上确保您是在有效的数组上操作。

当您从空散列{}开始时,对于任何给定的键,result[key]的值都将是nil --因为该键在该哈希中仍然不存在。

代码语言:javascript
复制
01:  if result.has_key?(key)
02:    result[key].push(word)
03:  else
04:    result[key] = [word]
05:  end

因此,第01行检查result散列中是否已经存在一个键--如果是,则可以使用表达式result[key]访问它,并假设它是一个数组,将另一个单词推入该数组。

如果键在result哈希中仍然不存在,那么,第04行通过赋值来设置它,该值是一个单一元素数组[word]

如果您更熟悉Ruby,那么您可以编写类似于下面的内容,并避免使用整个if-else舞蹈:

代码语言:javascript
复制
words.each do |word|
  key = word.split('').sort.join
  result[key] ||= []
  result[key] << word
end
票数 2
EN

Stack Overflow用户

发布于 2016-10-05 09:11:21

该程序通过对其字母(key = word.split('').sort.join)进行排序来计算每个单词的键。如果两个或更多的词是对方的字谜,他们将有相同的钥匙。

例如,单词neonnone的关键是enno

然后,在result哈希中添加单词。此散列包含前面讨论的anagram键作为键。哈希值是单词(字符串)的数组。

下面是附加注释的(重要)代码的其余部分:

代码语言:javascript
复制
# If there is an entry in the hash for the current anagram key 
if result.has_key?(key)
  # Then add the current word in the array, together with all the
  # other anagrams that are already there (because they share the
  # same key)
  result[key].push(word)
else
  # If the key has not yet been created, then create it and assign
  # as a value a new array that only contains the current word.
  result[key] = [word]
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39869703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档