Ruby: вычислить частоты строчных текстовых букв - PullRequest
0 голосов
/ 17 ноября 2018

Я создавал программу 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

Но я получаю эту ошибку при запуске метода отображения введите описание изображения здесь

Что означает ошибка и как ее решить?

1 Ответ

0 голосов
/ 17 ноября 2018

Основная проблема в том, что в calculateFrequencies вы используете неназначенную переменную: letters.Так, когда вы вызываете calculateFrequencies в display, letters = nil и вызов .clear в nil возвращает ошибку.

Это модифицированная версия кода с использованием 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: ◼︎
...