性格与字符串

时间:2011-12-29 04:04:52

标签: haskell

我是haskell的新手,我有一个问题(也就是家庭作业)。

所以,我有一个带有元组的列表 - 一个字符串和一个整数:

xxs :: [([Char], Integer)] 

我需要知道xxs中有多少字符串以给定字符开头。 让我举例说明:

foo 'A' [("Abc",12),("Axx",34),("Zab",56)]
Output: 2 

foo 'B' [("Abc",12),("Bxx",34),("Zab",56)]
Output: 1

到目前为止我的最佳尝试:

foo c xxs = length (foldl (\acc (x:xs) -> if x == c then c else x) [] xxs)

但是,当然,lambda表达式中有一些非常错误。

有什么建议吗? 感谢。

3 个答案:

答案 0 :(得分:4)

可以使用折叠,但我会建议另一种方式,它分三步解决问题:

  • 将输入列表转换为首字母列表。您可以map使用此
  • filter所有不符合给定Char
  • 的元素
  • 获取剩余列表的length

显然,第一步是最难的,但不像看起来那么难。要做到这一点,你只需要以某种方式组合函数fsthead,或者更容易,两次映射。

你可以把它写成一个简单的单行,但也许你应该从let开始:

foo c xxs =  let strings = map ...
                 firstLetters = map ...
                 filteredLetters = filter ...
             in length ...

答案 1 :(得分:2)

您的尝试存在一些问题:

  1. 您打算使用foldl构建较短的列表,然后使用其长度。虽然有可能,filter函数更适合该任务,因为@landei建议

  2. foldl可用于累积长度,而无需构建更短的列表。看到@WuXingbo的答案 - 他的答案是不正确的,但是一旦你意识到他的方法根本不需要length,你应该很容易找到正确的解决方案。

  3. 与常识有些矛盾,在惰性语言中foldrfoldl更快且使用更少的内存。你应该问你老师为什么。

答案 2 :(得分:0)

我会把foo重写为

foo :: Char -> [(String, Int)] -> Int
foo c = length . filter ((==c).head.fst)

fst获取双元素元组的第一个元素。

(==c)是一个单参数函数,可将其输入与c进行比较(有关更好的说明,请参阅http://www.haskell.org/tutorial/functions.html第3.2.1段)。