Stuck - Haskell编码的练习考试Q:返回字符串列表中最长的字符串

时间:2014-08-02 13:56:23

标签: string haskell mapping fold

完整的练习题考试问题是:

  

使用匿名函数和映射函数,定义Haskell   返回字符串列表中最长字符串的函数,例如   对于[“qw”,“asd”,“fghj”,“kl”]函数应返回“fghj”。

我尝试过这样做并继续失败并转向其他人,但我真的想知道如何解决这个问题。我似乎必须使用映射函数和匿名函数,但我不知道如何编写代码来使每个元素检查以找到最高的元素。

我知道使用像" foldr"这样的映射函数。可以让你对每个元素执行重复操作并返回一个结果,这就是我们想要对这个问题做的事情(检查字符串列表中最长的每个字符串,然后返回一个字符串)。

但是对于foldr,我不知道如何使用它来检查元素之间的检查,以确定哪些是最长的...#...任何帮助都将很乐意受到赞赏。

到目前为止,我一直在测试我是否可以使用foldr来测试每个元素的长度,但它甚至不起作用:

longstr :: [String] -> String
longstr lis = foldr (\n -> length n > 3) 0 lis

我对haskell很新,因为这是一个为期3个月的课程而且只有1个月我们会有一个小型考试

4 个答案:

答案 0 :(得分:5)

我说他们正在寻找一个简单的解决方案:

longstr xs = foldr (\x acc -> if length x > length acc then x else acc) "" xs

foldr就像一个迭代列表xs的每个元素的循环。它接收2个参数:x是元素,acc(对于累加器)在这种情况下是迄今为止最长的字符串。

如果到目前为止最长的字符串比我们保留的元素长,那么我们就改变它。

答案 1 :(得分:3)

另一个想法:

  1. 转换为元组列表:(长度,字符串)
  2. 取该列表的最大值(这是一对)。
  3. 返回由(2)返回的对的字符串。
  4. Haskell将按字典顺序比较对(a,b),因此(2)返回的对将来自长度最大的字符串。

    现在你只需编写一个最大函数:

    maximum :: Ord a => [a] -> a
    

    这可以使用foldr(或只是普通递归)来编写。

    要使用递归编写maximum函数,请填写空白:

    maximum [a] = ???       -- maximum of a single element
    maximum (a:as) = ???    -- maximum of a value a and a list as (hint: use recursion)
    

    maximum的基本情况以单个元素列表开头,因为maximum []在这里没有意义。

答案 2 :(得分:2)

您可以将列表映射到元组列表,包括(长度,字符串)。按长度排序(最大的第一个)并返回第一个元素的字符串。

https://stackoverflow.com/a/9157940/127059也有答案。

答案 3 :(得分:0)

这是一个从下到上构建你想要的东西的例子。

maxBy :: Ord b => (a -> b) -> a -> a -> a
maxBy f x y = case compare (f x) (f y) of
 LT -> y
 _  -> x

maximumBy :: Ord b => (a -> b) -> [a] -> Maybe a
maximumBy _ [] = Nothing
maximumBy f l  = Just . fst $ foldr1 (maxBy snd) pairs
 where
    pairs = map (\e -> (e, f e)) l 

testData :: [String]
testData = ["qw", "asd", "fghj", "kl"]

test :: Maybe String
test = maximumBy length testData

main :: IO ()
main = print test