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

String 针对Haskell编码的练习考试Q:返回字符串列表中最长的字符串,string,haskell,mapping,fold,String,Haskell,Mapping,Fold,完整的练习试题是: 使用匿名函数和映射函数定义Haskell 返回字符串列表中最长字符串的函数,例如。 对于[“qw”、“asd”、“fghj”、“kl”]函数应返回“fghj” 我试着这样做,但一直失败,并向其他人转移,但我真的很想知道如何解决这个问题。我似乎必须使用映射函数和匿名函数,但我不知道如何编写代码,使每个元素相互检查,以找到最高的元素 我知道,使用像“foldr”这样的映射函数可以使您对每个元素执行重复操作并返回一个结果,这就是我们要对这个问题执行的操作(检查字符串列表中每个字符串

完整的练习试题是:

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

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

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

但是有了foldr,我不知道如何使用它在elments之间进行检查,看看哪个是“最长的”。。。任何帮助都将不胜感激

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

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

我对haskell很陌生,因为这是一门为期3个月的课程,只上了1个月,我们还有一个小测验要考

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


还有一个答案。

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

还有一个答案。

另一个想法:

  • 转换为元组列表:(长度,字符串)
  • 取该列表的最大值(即某一对)
  • 返回由(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[]
    在这里没有意义。

    另一个想法:

  • 转换为元组列表:(长度,字符串)
  • 取该列表的最大值(即某一对)
  • 返回由(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[]
    在这里没有意义。

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

    longstr xs = foldr (\x acc -> if length x > length acc then x else acc) "" xs
    
    foldr
    就像一个循环,在列表的每个元素上迭代
    xs
    。它接收两个参数:
    x
    是元素,
    acc
    (对于累加器)是迄今为止最长的字符串


    在这种情况下,如果到目前为止最长的字符串比我们保留的元素长,那么我们将对其进行更改。

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

    longstr xs = foldr (\x acc -> if length x > length acc then x else acc) "" xs
    
    foldr
    就像一个循环,在列表的每个元素上迭代
    xs
    。它接收两个参数:
    x
    是元素,
    acc
    (对于累加器)是迄今为止最长的字符串


    在这种情况下,如果到目前为止最长的字符串比元素长,我们将保留它,否则我们将更改它。

    下面是一个从下至上构建所需内容的示例

    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
    

    下面是一个从下到上构建所需内容的示例

    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
    

    非常感谢,这听起来肯定会奏效。然而,我的问题仍然是一样的——我不知道如何“排序”或递归模式,或者只是比较列表、元组等中的元素并对它们进行排序的模式。回答问题,如果不够的话,请提供一个链接。非常感谢,这听起来肯定会起作用。然而,我的问题仍然是一样的——我不知道如何“排序”或递归模式,或者只是比较列表、元组等中的元素并对它们进行排序的模式。回答这个问题,如果不够的话,请提供一个链接。我不确定我是否会将折叠调用为映射函数。然而,由于fold函数有两个参数——当前元素和累加器——使用fold的一种方法可能是将迄今为止最长的元素分配给累加器。我不确定是否将fold函数称为映射函数。然而,由于fold函数有两个参数——current元素和累加器——使用fold的一种方法可能是将迄今为止最长的元素分配给累加器。好的,我制定了如何执行此操作的基本思想,我在ho上找不到任何可以直接“获取该列表的最大值”的内容。你能告诉我做这件事的方法吗?我在我的答案中又加了一些。好的,我列出了做这件事的基本思路,我在ho上找不到任何东西可以直接“最大限度地利用这个列表”。你能告诉我做这件事的方法吗?我在回答中又加了一些。用它做
    foldr1
    ,你就可以去掉空的string@ThreeFx这将是一个稍微不同的函数,因为它们在空列表输入上的行为不同。您想要哪一个取决于您是否希望它在空列表上抛出错误或提供空字符串(或执行其他操作)。将
    foldr1
    从中取出,您可以删除空字符串string@ThreeFx这将是一个稍微不同的函数,因为它们在空列表输入上的行为不同。你想要哪一个要看情况