Najprostszym rozwiązaniem jest użycie Data.Map
do przechowywania pośredniego mapowania z charakterem częstotliwości. Możesz łatwo skonstruować liczbę za pomocą fromListWith
. Ponieważ sortowane jest Data.Map
, dostajesz je w porządku ASCII za darmo.
λ> :m + Data.Map
λ> let input = "happy"
λ> toList $ fromListWith (+) [(c, 1) | c <- input]
[('a',1),('h',1),('p',2),('y',1)]
Więc co tu się dzieje?
Chodzi o to, aby zbudować Data.Map
(mapę drzewa), używając znaków jako klawiszy i częstotliwości jako wartości.
Najpierw pobieramy łańcuch wejściowy i robimy krotki każdego znaku, podając 1
, aby wskazać jedno wystąpienie.
λ> [(c, 1) | c <- input]
[('h',1),('a',1),('p',1),('p',1),('y',1)]
Następnie używamy fromListWith
budować posortowaną mapę z tych par klucz-wartość poprzez wielokrotne wstawianie każdą parę klucz-wartość w mapie. Dajemy mu także funkcję, która będzie używana, gdy klucz był już na mapie. W naszym przypadku używamy (+)
, więc gdy postać jest widziana wiele razy, dodajemy liczbę do istniejącej sumy.
Na koniec zamieniamy mapę z powrotem na listę krotek klucz-wartość za pomocą toList
.
Musisz uporządkować wejście pierwsze obejmuje przypadki, jak '' „pappy” gdzie wystąpienia 'p' nie sąsiadują. – hammar
Dzięki, naprawione. :-) –
i zauważ, że '(\ x -> (head x, length x)) == head &&& length', gdzie' (&&&) 'pochodzi od' Control.Arrow'. – Conal