下面我写了一段代码,它应该计算字符串中字符出现的次数,并以散列形式显示结果。我的想法是在我计算它之后立即删掉字符串中的那个字母,以便我们不会多次将它放入哈希值。
我的原始代码是:
def letter_count_spec(str)
letter_count = Hash.new #create hash
letter = str.split('') #separate letters
letter.each{ |e|
if( /[A-Za-z0-9]/.match(e) )
occurances = letter.count{ |x| x==e}
letter_count[e] = occurances
letter.delete(e) #delete letter
end
}
return letter_count
end
letter_count_spec("cat")
结果:=> {" c" => 1," t" => 1}
我输了" a"!
所以我尝试了这个:
def letter_count_spec(str)
letter_count = Hash.new #create hash
letter = str.split('') #separate letters
letter.each{ |e|
if( /[A-Za-z0-9]/.match(e) )
occurances = letter.count{ |x| x==e}
letter_count[e] = occurances
end
}
letter.each{ |e|
letter.delete(e) #delete letter
}
return letter_count
end
letter_count_spec("cat")
result => {" a" => 1," c" => 1," t" => 1}
为什么我需要再次通过数组删除?
答案 0 :(得分:1)
迭代期间对集合的修改可能会导致问题,这在评论中有说明。
字计数算法通常包括用于跟踪字数的散列,以及用于遍历内容的迭代器。您无需修改原始集合。这是一个O(n)解决方案,假设在一般情况下散列的更新复杂度为O(1)。但是,帖子中的计数和删除方法具有O(n ^ 2)复杂度(如果有效)。
def letter_count_spec(str)
letter_count = Hash.new(0) # create hash, and use 0 as the default value
letter = str.split('') # separate letters
letter.each do |e|
if /[A-Za-z0-9]/.match(e)
letter_count[e] += 1 # increment count
end
end
letter_count
end
BTW,在Ruby中,将do ... end
用于多行阻塞是一种惯例,除非在某些情况下需要{}
。