【问题标题】:Comparing list length比较列表长度
【发布时间】:2011-10-11 17:41:43
【问题描述】:

我有一个列表,比如说:

import Data.List

xs = [[1,2], [1,2,3], [2,3]]

我想获取包含最多项目的内部列表,在本例中为 [1,2,3]

我正在尝试使用 Data.List 库中的 maximumBy 函数:

maximumBy (compare `on` length) xs

但我收到以下错误:not in scope 'on'

谁能告诉我出了什么问题,或者您是否有更好的方法来获取列表?

【问题讨论】:

  • 作为练习,尽量不要使用on,而是手动将参数写入maximumBymaximumBy (\x y -> ...) xs

标签: list haskell


【解决方案1】:

或者你可以让它更明确一点:

xs = [[1,2],[1,2,3],[2,3]]
ordLen a b = compare (length a) (length b)
maximumBy ordLen xs

也许这样更容易理解。

【讨论】:

    【解决方案2】:

    on 定义在 Data.Function 中,所以你需要导入它。

    或者,您可以使用Data.Ord 中的comparing

    maximumBy (comparing length) xs
    

    【讨论】:

    • 谢谢,这工作...不知道我需要另一个库。 Haskell Noob 在这里。
    • 是的,我会...需要等待 5 分钟!
    • @Special--k Hoogle 非常适合确定需要从哪个模块导入函数。
    【解决方案3】:

    试试

    maximumBy (comparing length)
    

    maximumBy (on compare length)
    

    maximumBy (compare `on` length)
    

    【讨论】:

      【解决方案4】:

      虽然将maximumBycomparing lengthcompare `on` length 一起使用对于短列表来说效果很好,但请注意,如果列表很长,这不是一个非常有效的解决方案,因为每次算法都会比较两个列表,它会重新计算它们的长度。

      例如,如果我们有一个很长的第一个列表,然后是许多短列表,则使用maximumBy 将非常慢,因为第一个列表的长度将在每个步骤中重新计算。

      > import Data.List
      > import Data.Ord
      > let xs = replicate 50000 'a' : replicate 50000 "b"
      > maximumBy (comparing length) xs
      <snip>
      (16.09 secs, 98338680 bytes)
      

      我们可以通过缓存列表的长度来获得更高效的解决方案:

      > let longest xss = snd $ maximumBy (comparing fst) [(length xs, xs) | xs <- xss]
      > longest xs
      <snip>
      (0.35 secs, 91547296 bytes)
      

      当然,如果您的列表很小,这可能不会有很大的不同,但值得注意。

      【讨论】:

      • maximumBy 没有其他非重新计算版本吗?顺便说一句,你如何让ghci 打印运行时?
      • @Tarrasch:我认为不在任何标准库中。使用:set +s 启用每次评估的计时。
      • @Tarrasch:显然,there was a proposal to add such functions,但它似乎已经被放弃了。
      【解决方案5】:

      受 hammar 解决方案的启发,但只需通过列表即可:

      import Data.List
      
      longest = snd . foldl' cmp (0,[]) where
         cmp maxPair@(maxLen, _) list = 
            let len = length list 
            in if len > maxLen then (len, list) else maxPair  
      

      【讨论】:

        猜你喜欢
        • 2021-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-25
        • 2017-12-24
        • 2019-02-17
        • 1970-01-01
        相关资源
        最近更新 更多