2014-11-14 3 views
0

Так у меня есть следующий код, который подсчитывает частоту каждой буквы в строке (или в данном конкретном случае из файла):Подсчет символов

def letter_frequency(file) 
    letters = 'a' .. 'z' 
    File.read(file) . 
    split(//) . 
    group_by {|letter| letter.downcase} . 
    select {|key, val| letters.include? key} . 
    collect {|key, val| [key, val.length]} 
end 

letter_frequency(ARGV[0]).sort_by {|key, val| -val}.each {|pair| p pair} 

который прекрасно работает, но я хотел бы посмотрите, есть ли что-нибудь, чтобы что-то сделать в рубине, что похоже на это, но чтобы поймать все различные возможные символы? т.е. пространства, запятые, периоды и все между ними. Я предполагаю, что проще сказать, есть ли что-то похожее на 'a' .. 'z', которое содержит все символы? Надеюсь, это имеет смысл.

ответ

1

Вам не нужен диапазон когда вы пытаетесь подсчитать все возможные символы, потому что каждый возможный символ - это домен. Вы должны создавать только диапазон, когда вам необходимо использовать подмножество указанного домена.

Это, вероятно, быстрее, реализация, которая подсчитывает все символы в файле:

def char_frequency(file_name) 
    ret_val = Hash.new(0) 
    File.open(file_name) {|file| file.each_char {|char| ret_val[char] += 1 } } 
    ret_val 
end 

p char_frequency("1003v-mm") #=> {"\r"=>56, "\n"=>56, " "=>2516, "\xC9"=>2, ... 

Для справки я this test file.

+0

Это имеет смысл. В итоге я сделал что-то очень похожее. Мне просто интересно, есть ли какая-то легкая одна строка, которая будет инкапсулировать каждый возможный символ, имеет смысл, если нет, однако. – Luminusss

+0

Существует несколько методов, которые касаются символов, которые могут представлять интерес для вашего случая, например ['ascii_only?'] (Http://www.ruby-doc.org/core-2.1.4/String.html # метод-я-ascii_only-3F). Однако я не знаю способа представления «действительного символа» в Ruby. Например, 'each_char' либо вернет допустимый символ, либо поднимет исключение, если он не сможет правильно закодировать его из входного файла. –

0

Он не может использовать много Рубина магии с диапазонами, но простой способом построить счетчик символов, который перебирает каждый символ в строке и подсчитывает итоги:

class CharacterCounter 
    def initialize(text) 
    @characters = text.split("") 
    end 

    def character_frequency 
    character_counter = {}  
    @characters.each do |char| 
     character_counter[char] ||= 0 
     character_counter[char] += 1 
    end 

    character_counter 
    end 

    def unique_characters 
    character_frequency.map {|key, value| key} 
    end 

    def frequency_of(character) 
    character_frequency[character] || 0 
    end 
end 

counter = CharacterCounter.new("this is a test") 
counter.character_frequency # => {"t"=>3, "h"=>1, "i"=>2, "s"=>3, " "=>3, "a"=>1, "e"=>1} 
counter.unique_characters # => ["t", "h", "i", "s", " ", "a", "e"] 

counter.frequency_of 't' # => 3 
counter.frequency_of 'z' # => 0 
Смежные вопросы