Haskell中的频率表只有列表理解,在字符串中查找字符的频率

时间:2016-08-23 15:09:16

标签: list haskell frequency huffman-code

我是Haskell的新手,试图学习一些东西并完成我给出的任务。我想在String中找到字符数但不导入Haskell模块。

我需要实现一个频率表,我想更多地了解Haskell中的编程以及如何实现它。 我将我的FreqTable作为一个元组,其中包含字符和出现的字符数' char'在一个字符串中。

type FreqTable = [(Char, Int)]

我一直在寻找几天和长时间的解决方案,以找到一些有用的例子。

我的函数或任务id中的函数声明如下:

fTable :: String -> FreqTable

我知道正确答案可以是:

map (\x -> (head x, length x)) $ group $ sort

map (head &&& length) . group . sort

[ (x,c) | x <- ['A'..'z'], let c = (length . filter (==x)), c>0 ]

我可以让这个与我的列表完全一致,但我发现这是一个可选的解决方案。我得到了一个错误,我可以通过上面的列表理解来解决这个问题。

 Couldn't match expected type ‘String -> FreqTable’
            with actual type ‘[(Char, [Char] -> Int)]’
In the expression:
  [(x, c) |
     x <- ['A' .. 'z'], let c = (length . filter (== x)), c > 0]
In an equation for ‘fTable’:
    fTable
      = [(x, c) |
           x <- ['A' .. 'z'], let c = (length . filter (== x)), c > 0]

可以请某人与我分享并向我解释一种检查字符频率的简单方法,而无需导入Data.List或Map

2 个答案:

答案 0 :(得分:4)

你还没有包括你应该过滤的内容和

的长度
[ (x,c) | x <- ['A'..'z'], let c = (length . filter (==x)), c>0 ]
--                                 ^_____________________^ 
-- this is a function from a String -> Int
-- you want the count, an Int
-- The function needs to be applied to a String

要应用它的字符串是fTable

的参数
fTable :: String -> FreqTable
fTable    text   =  [ (x,c) | x <- ['A'..'z'], let c = (length . filter (==x)) text, c>0 ]
--        ^--------------------------------------------------------------------^

答案 1 :(得分:1)

列表:['A'..'z']是这个字符串:

"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz"

所以你要迭代大写和小写字母(和一些符号)。这就是为什么你有一个元组,例如'A'和'a'。

如果要执行不区分大小写的计数,则必须执行不区分大小写的比较而不是直接相等。

import Data.Char

ciEquals :: Char -> Char -> Bool
ciEquals a b = toLower a == toLower b

然后:

ftable text = [ (x,c) | x <- ['A'..'Z'], 
                      , let c = (length . filter (ciEquals x)) text,
                      , c > 0 ]