【问题标题】:Delete from where?从哪里删除?
【发布时间】:2014-06-04 09:16:57
【问题描述】:

下面我编写了一段代码,它应该计算字符串中字符的出现次数并以哈希的形式显示结果。我的想法是在我数完之后立即删除字符串中的那个字母,这样我们就不会将它多次放入哈希中。

我原来的代码是这样的:

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")

结果 => {"a"=>1, "c"=>1, "t"=>1}

为什么我需要再次遍历数组才能删除?

【问题讨论】:

标签: ruby hash each


【解决方案1】:

在迭代过程中修改collection可能会出现问题,在评论中有说明。

字数统计算法通常涉及一个散列来跟踪字数,以及一个迭代器来遍历内容。您不需要修改原始集合。这是一个 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

顺便说一句,在 Ruby 中,约定使用 do ... end 表示多行块,除非在某些情况下需要 {}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-19
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 2015-09-29
    • 2021-06-06
    • 2015-06-13
    • 2012-06-18
    相关资源
    最近更新 更多