2014-09-01 10 views
6

Próbuję utworzyć program w języku Ruby, który zlicza ile razy razem pojawiają się dwie litery. To jest to, co jest napisane w pliku Czytam:Zliczanie ile razy razem pojawiają się dwie litery

hola 
chau 

I to właśnie staram się dostać:

ho;ol;la;ch;ha;au; 
1;1;1;1;1;1; 

nie mogę zmusić go do poprawnej pracy. To jest mój kod do tej pory:

file = File.read(gets.chomp) 
todo = file.scan(/[a-z][a-z]/).each_with_object(Hash.new(0)) { 
    |a, b| b[a] += 1 
} 

keys = '' 
values = '' 

todo.each_key { 
    |key| keys += key + ';' 
} 
todo.each_value { 
    |value| values += value.to_s + ';' 
} 

puts keys 
puts values 

Jest to wynik Dostaję:

ho;la;ch;au; 
1;1;1;1; 

Dlaczego nie dostaję każdą kombinację znaków? Co powinienem zamieścić w moim regexie, żeby policzyć każdą kombinację znaków?

Odpowiedz

9

Ponieważ postacie są nachodzące na siebie, do przechwycenia zachodzących na siebie znaków należy użyć znaku "do przodu".

(?=([a-z][a-z])) 

DEMO

+1

Bardzo pouczający, Avinash. Wcześniej nie widziałem grupy przechwytującej w grupie obserwującej. Bardzo potężny. –

+0

Mogłeś zamiast tego użyć pozytywnego spojrzenia "(? <= ([A-z] [a-z]))", o którym wspomniałeś w komentarzu, który skasowałeś. Myślę, że zasługuje na wzmiankę. –

2

Jest to jeden sposób.

def char_pairs(str) 
    str.split(/\s+/).flat_map { |w| w.chars.each_cons(2).map(&:join) } 
        .each_with_object({}) { |e,h| h[e] = (h[e] ||= 0) + 1 } 
end 

char_pairs("hello jello") 
    #=> {"he"=>1, "el"=>2, "ll"=>2, "lo"=>2, "je"=>1} 

char_pairs("hello yellow jello") 
    #=> {"he"=>1, "el"=>3, "ll"=>3, "lo"=>3, "ye"=>1, "ow"=>1, "je"=>1} 

Posiadanie skrótu, jest łatwo przekonwertować go na dowolny format wyjściowy.

Powiązane problemy