【问题标题】:Stuck - Practice exam Q for Haskell coding: Return the longest String in a list of StringsStuck - Haskell 编码练习考试 Q:返回字符串列表中最长的字符串
【发布时间】:2014-08-02 13:56:22
【问题描述】:

完整的练习题是:

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

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

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

但是对于 foldr,我不知道如何使用它在元素之间进行检查以查看哪个“最长”...任何帮助将不胜感激。

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

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

我对 Haskell 很陌生,因为这是一个为期 3 个月的课程,而且只有 1 个月,我们即将举行一场小型考试

【问题讨论】:

  • 我不确定是否将折叠称为映射函数。然而,由于折叠函数有两个参数 - 当前元素和累加器 - 使用折叠的一种方法可能是将迄今为止最长的元素分配给累加器。

标签: string haskell mapping fold


【解决方案1】:

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

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

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

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

【讨论】:

  • foldr1去掉,你就可以删除空字符串了
  • @ThreeFx 这将是一个稍微不同的函数,因为它们在空列表输入上的行为不同。您想要哪一个取决于您是否希望它在空列表上引发错误或给出空字符串(或执行其他操作)。
【解决方案2】:

另一个想法:

  1. 转换为元组列表:(长度,字符串)
  2. 取该列表中的最大值(一些对)。
  3. 返回由 (2) 返回的对的字符串。

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 [] 在这里没有意义。

【讨论】:

  • 好的,我制定了如何做到这一点的基本思路,我在 ho 上找不到任何内容来直接“获取该列表的最大值”。你能告诉我这样做的方法吗?
  • 我在回答中添加了更多内容。
【解决方案3】:

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

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

【讨论】:

  • 非常感谢,这听起来肯定会奏效。然而,我的问题仍然是相同的 - 我不知道如何“排序”或递归模式或只是模式来比较列表、元组等中的元素并对其进行排序。
  • 回答问题,如果不够,请提供链接。
【解决方案4】:

这是一个自下而上构建所需内容的示例。

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

【讨论】:

    猜你喜欢
    • 2021-09-19
    • 2023-03-21
    • 2023-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多