我接到一项任务,要写一个Anagram程序,下面是我想出来的
class Anagram
attr_accessor :anagram_value
def initialize(value)
@anagram_value = value
end
def matches(*collection)
matches = []
matches = collection.select do |word|
(word.length == @anagram_value.length) ? is_an_anagram?(word) : false
end
return matches
end
def is_an_anagram?(word)
return get_word_ord_sum(word) == get_word_ord_sum(@anagram_value)
end
def get_word_ord_sum(word)
sum = 0
word.split("").each { |c| sum += c.ord }
Areturn sum
end
end令人惊讶的是,上面的方法在使用下面的案例时是有效的。
it "detects multiple Anagrams" do
subject = Anagram.new("allergy")
matches = subject.matches('gallery', 'ballerina', 'regally', 'clergy', 'largely', 'leading');
expect(matches).to eq ['gallery', 'regally', 'largely']
end它实际上失败了以下几点
it "no matches" do
subject = Anagram.new("abc")
matches = subject.matches("bbb")
expect(matches).to eq []
end发布于 2015-09-10 15:44:49
问题是97 + 98 + 99 == 98 + 98 + 98。也就是说,字符数字的总和并不唯一地映射到给定字符串的直方图。
修复它的一种方法是将get_word_ord_sum映射到其他东西。例如,“最小的”字谜就可以了。但是,请注意这是O(nlgn)
word.chars.sort.join
编辑:扩展使用Array#group_by的想法,将get_word_ord_sum替换为:
word.downcase.chars.group_by(&:itself)现在你将得到一个类似直方图的散列,并且由于比较散列时键的顺序并不重要,所以你将在O(n)中得到你想要的结果。
发布于 2015-10-05 10:22:09
这可能会有帮助。
words = ['demo', 'none', 'tied', 'evil', 'dome', 'mode', 'live',
'fowl', 'veil', 'wolf', 'diet', 'vile', 'edit', 'tide',
'flow', 'neon']
groups = words.group_by { |word| word.split('').sort }退货分组:
{"d","e","m","o"=>"demo","dome","mode","e","n","n","o"=>"none",“霓虹灯”,"d","e","i",“t”“=>”,“=>”,"edit",“=>”,"e","i","l",“v”=>“=>”,"live",“面纱”,“邪恶”,"f","l","o","w"=>"fowl","wolf","flow"}
groups.each { |x, y| p y } 返回每个值:
"demo","dome","mode“
“无”,“霓虹灯”
“平局”,“节食”,“编辑”,“潮流”
“邪恶”,“活着”,“面纱”,“邪恶”
“家禽”,“狼”,“流”
https://stackoverflow.com/questions/32495784
复制相似问题