ruby - Ruby:计算字符串文本字母的频率
问题描述
我正在创建一个 ruby 程序,它将计算每个字母出现在我的文本中的频率,并将其作为哈希返回。
下面是我的代码:
class LetterHistogram
attr_reader :letters
attr_accessor :text
def initialize(t = "Hello World!")
@text = t
end
def display
calculateFrequencies
("A".."Z").each {|x| puts "#{x}: " + "*" * letters[x]}
end
private
attr_writer :letters
def calculateFrequencies
calcuFreq = String.new(text)
calcuFreq.upcase!.gsub!(/\W+/, '')
letters.clear
letters.default = 0
calcuFreq.each_char {|char| letters[char] += 1}
end
end
但是当我运行显示方法时出现此错误在 此处输入图像描述
错误是什么意思以及如何解决?
解决方案
主要问题是calculateFrequencies
您使用的是未分配的变量:letters
. 因此,当您调用calculateFrequencies
indisplay
时,letters = nil
调用.clear
onnil
返回错误。
这是代码的修改版本,使用的是 snake_case(这是 Ruby 编写标准)。
class LetterHistogram
attr_accessor :text
def initialize(t = "Hello World!")
@text = t
end
def display
calculate_frequencies.each { |letter, freq| puts "#{letter}: #{freq}"}
end
private
def calculate_frequencies
freq = @text.upcase.gsub!(/\W+/, '').each_char.with_object(Hash.new(0)) { |letter, freq| freq[letter] += 1 }
freq.sort_by{ |letter, freq| freq }.reverse # just to sort
end
end
实例化一个对象并调用.display
它:
senctence = LetterHistogram.new
senctence.display
#=> L: 3
#=> O: 2
#=> D: 1
#=> R: 1
#=> W: 1
#=> E: 1
#=> H: 1
这个怎么运作
为了计算频率,我使用了由以下内容填充的哈希:https ://ruby-doc.org/core-2.5.1/Enumerable.html#method-i-each_with_object
freq
从你打印出来calculate_frequencies
可以看到:
#=> {"H"=>1, "E"=>1, "L"=>3, "O"=>2, "W"=>1, "R"=>1, "D"=>1}
或者,如果您还想要不使用的字母,您可以将
freq
所有值的散列初始化为 0,然后更新散列,如下所示:
freq = ("A".."Z").each_with_object({}) { |letter, freq| freq[letter] = 0 }
"Hello World!".upcase.gsub!(/\W+/, '').each_char { |letter| freq[letter] += 1 }
#=> {"A"=>0, "B"=>0, "C"=>0, "D"=>1, "E"=>1, "F"=>0, "G"=>0, "H"=>1, "I"=>0, "J"=>0, "K"=>0, "L"=>3, "M"=>0, "N"=>0, "O"=>2, "P"=>0, "Q"=>0, "R"=>1, "S"=>0, "T"=>0, "U"=>0, "V"=>0, "W"=>1, "X"=>0, "Y"=>0, "Z"=>0}
最后,打印出直方图:
freq.each { |letter, freq| puts "#{letter}: " + "◼︎" * freq if freq > 0 }
#=> D: ◼︎
#=> E: ◼︎
#=> H: ◼︎
#=> L: ◼︎◼︎◼︎
#=> O: ◼︎◼︎
#=> R: ◼︎
#=> W: ◼︎
推荐阅读
- c++ - C ++为什么我的第一个数据输入 getline(cin, array[x]) 在同一行并且损坏了,而我的第二个数据输入很好?
- kernel - 我在哪里可以找到 QNX 内核转储?
- azure-devops - azure devop build pipeline not triggering
- kotlin - 无法将可为空的属性与 tornadofx 视图模型绑定
- python - 如何向散点图矩阵中的每个散点图添加线性回归线?
- php - PHP:get_object_vars 用于未初始化的类型字段以获取字段名称
- c++ - const T& 怎么可能引用文字?
- apache - Apache RewriteRule 不适用于单一输入
- python - 如何使用 if 语句在数据框中输入值?
- flask - 比较矩对象 jinja2