【问题标题】:Frequency table in Haskell with list comprehension only, find frequency of characters in a StringHaskell中的频率表仅具有列表理解,查找字符串中字符的频率
【发布时间】:2016-08-23 15:09:16
【问题描述】:

我是 Haskell 的新手,正在尝试学习一些东西并完成交给我的任务。我想查找字符串中的字符数,但不导入 Haskell 模块。

我需要实现一个频率表,并且我想了解更多关于 Haskell 编程以及如何做到这一点的信息。 我将 FreqTable 作为一个元组,其中包含字符和字符串中“char”的出现次数。

type FreqTable = [(Char, Int)]

我一直在寻找解决方案几天和很长时间以找到一些工作示例。

我的函数或者task 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

【问题讨论】:

  • cString -&gt; Int 类型的函数,但您在要求它是 Int (c&gt;0) 类型的上下文中使用。好像忘记绑定变量了:\list -&gt; [ (x,c) | ... c = length (filter (==x) list) ... ]
  • “不导入任何东西”是什么意思?列表推导式使用列表单子,即函数 map、concat 和 guard(被语法糖隐藏)。这不是已经导入了吗?
  • 你能把这个问题清理一下吗?我们不需要您的生活故事或您以后打算问什么问题。
  • @V.Semeria,这实际上并不是它们的实现方式,尽管它们可能是。我认为 OP 意味着 Prelude-only。
  • 我的意思是没有 Data.List 或 Map 。即使他们在后台为排序和组工作,您也必须进行导入

标签: list haskell frequency huffman-code


【解决方案1】:

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

[ (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 ]
--        ^--------------------------------------------------------------------^

【讨论】:

  • 我可以写成 = \ text -> ....... ??
  • @PeterPan 为什么不试试呢?
  • 在下班路上的公交车上 :) 在手机上打字,但我会在我步行回家时直接尝试 :)
  • @Cidec 你有什么建议为什么我仍然收到如下错误消息吗?
  • 好的,我现在知道这完全是因为字母大小的不同。有人可以帮我在检查频率之前如何更改字符串中字母的大小吗?我如何修改它: \text -> [ (x,c) | x 0 ] ?
【解决方案2】:

列表:['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 ]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-23
    相关资源
    最近更新 更多