我已经解决了一个问题,该问题要求您编写一个方法来确定所提供的数组中的哪些单词是字形,并在输出中将字形组合到一个子数组中。
我已经用典型的方法解决了这个问题,那就是对单词进行排序,并根据排序后的字符将它们分组到一个哈希表中。
当我最初开始寻找这样做的方法时,我注意到String#sum存在,它将每个字符的序数加在一起。
我想试着找出一些方法来确定一个基于sum的变形词。例如,"cars“和"scar”都是字形,它们的sum是425。
给定%w[cars scar for four creams scream racs]的输入,期望的输出(我已经使用散列解决方案得到)是:[[cars, scar, racs],[for],[four],[creams,scream]]。
它看起来像是在做这样的事情:
input.each_with_object(Hash.new []) do |word, hash|
hash[word.sum] += [word]
end是一种方法,它给出了一个散列,其中关键字"425“的值是”cars“,”racs“,”scar“。我认为我缺少的是将其转换为预期的输出格式。
发布于 2012-03-01 22:40:27
不幸的是,我不认为String#sum是解决这个问题的可靠方法。
考虑一下:
"zaa".sum # => 316
"yab".sum # => 316相同的金额,但不是字谜。
相反,如何按字符的排序顺序对它们进行分组?
words = %w[cars scar for four creams scream racs]
anagrams = words.group_by { |word| word.chars.sort }.values
# => [["cars", "scar", "racs"], ["for"], ["four"], ["creams", "scream"]] 发布于 2012-03-01 22:24:09
要获得所需的输出格式,只需使用hash.values。但请注意,仅在单词中使用字符代码的总和在某些输入上可能会失败。当两个单词中的字符代码不是字形时,它们的和有可能是相同的。
如果你使用一种不同的算法来组合字符代码,错误地将单词识别为“anagram”的机会可以降低很多,但仍然不是零。基本上,您需要某种散列算法,但其属性是散列值的顺序无关紧要。也许可以将每个字符映射到不同的随机位串,然后取字符串中每个字符的位串总和?
这样,任何两个非字谜给你一个假阳性的机会将大约是2 ** bitstring_length。
发布于 2012-03-01 23:00:13
words = %w[cars scar for four creams scream racs]
res={}
words.each do |word|
key=word.split('').sort.join
res[key] ||= []
res[key] << word
end
p res.values
[["cars", "scar", "racs"], ["for"], ["four"],["creams", "scream"]]https://stackoverflow.com/questions/9517745
复制相似问题