0

これは以前の質問を参照しています。

Haskell の文字列のパーセンテージ

現時点では、返されるのはアルファベット順ですが、サイズ順で、パーセンテージが最も高い文字から始まり、下に向かっていますか?

4

1 に答える 1

1

次のような関数が必要です

letterFrqs :: String -> [(Char, Float)]

letterFrqs "PLATYPUS" == [('A',36),('P',18),('L',9),('S',9),('T',9),('U',9),('Y',9)]

与えられた

frqLetters :: String -> [(Char, Float)]

frqLetters "PLATYPUS" == [('A',36),('L',9),('P',18),('S',9),('T',9),('U',9),('Y',9)]

だからあなたが必要とするのは

letterFrqs = sortEm . frqLetters

sortEm :: [(Char, Float)] -> [(Char, Float)]

どのように書くことができますsortEmか?まあ、私たちはsortそのままFloatsをすることができsort :: [Float] -> [Float]ます. そのソートをタプルに取り入れたいと思います。

一般に、Haskell 関数には、似た名前のいとこがある場合があります。この場合、 にsort :: Ord a => [a] -> [a]は という名前のいとこがいsortBy :: (a -> a -> Ordering) -> [a] -> [a]ます。ここでの違いは、Ordインスタンスが「インライン化」されていることです。もっと具体的に言うと、Ord

instance Eq a => Ord a where
  compare :: a -> a -> Ordering

したがって、の制約を、インスタンスを定義する正確な関数 にsortBy置き換えるだけであることがわかります。実際、それはまさにそのように実装されていますsortOrdOrdcomparesort

sort = sortBy compare

2番目の要素(私たちのs!)を比較するだけのタプルsortEmのインスタンスと同等のコードを書くことで書くことができます。OrdFloat


では、どうすればよいのでしょうか。さて、Ordインスタンスを に使用できますFloat

compareOurTuples (char1, percent1) (char2, percent2) = compare percent1 percent2

sortEm = sortBy compareOurTuples

さて、Haskell をよく見ている人は、次のcompareOurTuplesように書くこともできることに気付くかもしれません。

compareOurTuples tup1 tup2 = compare (snd tup1) (snd tup2)

これは一般的なイディオムで、関数を「2 回」事前に構成するようなものです。と呼ばれonて入っていData.Functionます。

compareOurTuples = compare `on` snd

しかし、これはandを組み合わせたかなり一般的なイディオムであるため、これにも特別な名前が付けられています。私たちは持っていますcompareonData.Ord

comparing f = compare `on` f

そのため、実際に書いている間は非常に経済的sortEmです。

sortEm = comparing snd

そして、これはおそらく誰かが実際にこのコードを書く方法です。

letterFrqs = sortBy (comparing snd) . frqLetters

今では英語のように読めます。

于 2013-10-24T22:03:17.047 に答える