【问题标题】:Haskell - List of combinations of elements from list of listsHaskell - 列表列表中元素组合的列表
【发布时间】:2021-03-02 00:48:40
【问题描述】:

假设我有一些列表[[a, b], [c], [d, e, f], ...],其中列表中的列表可以是任意长度。我已经对列表进行了排序,使得最短的列表排在第一位,并且我想生成列表中所有元素组合的列表,以便我得到一个列表[[a, c, d, ...], [a, c, e, ...], [a, c, f, ...], [b, c, d, ...], ...],即通过更改从中选择的元素来生成组合最后的列表首先,向上移动列表以更改类似于计数的元素。

使用这个列表,我将在列表的头部使用惰性求值,因为我只需要 1 个满足谓词的列表。如何生成列表?

【问题讨论】:

    标签: haskell functional-programming list-comprehension nested-lists combinatorics


    【解决方案1】:

    你用列表推导标记了这个:

    pCombs pred xs = take 1 [ ys | ys <- sequenceAL xs, pred ys]
    
    sequenceAL (xs:t)     = [ x : ys  | x <- xs, ys <- sequenceAL t]
    sequenceAL []         = [ [] ]
    sequenceAL [xs]       = [ [x]     | x <- xs]
    sequenceAL [xs,ys]    = [ [x,y]   | x <- xs, y <- ys]
    sequenceAL [xs,ys,zs] = [ [x,y,z] | x <- xs, y <- ys, z <- zs]
    --- ....
    

    列表推导就像嵌套循环。

    可以看出,sequenceALsequenceA 专门用于列表,[])枚举其参数列表中所有序列的笛卡尔积(最后一个“旋转”最快)。由于该列表的长度是任意的,因此元素被收集到列表中,而不是元组中。

    我们也可以定义

    sequenceAL (xs:t)     = [ x : ys  | ys <- sequenceAL t, x <- xs]
    

    结果列表中的 first 元素旋转得最快。枚举的顺序可能没那么重要,它可以帮助解决内存问题。请参阅haskell running out of memory with finite lists 了解更多信息。

    另外,如果您的谓词可以应用于部分结果列表以提前清除一些列表,则应该这样做,将过滤与生成步骤编织在一起,以减少枚举空间。换句话说,尽早测试,以防止徒劳的枚举。

    【讨论】:

      【解决方案2】:

      是的,这是sequenceA :: (Applicative f, Traversable t) =&gt; t (f a) -&gt; f (t a)的特例:

      Prelude> sequenceA ["ab", "c", "def"]
      ["acd","ace","acf","bcd","bce","bcf"]
      

      例如,我们在这里设置f ~ []t ~ []a ~ CharSequenceA 在这里相当于:

      -- sequenceA for f ~ [] and t ~ []
      sequenceAList [] = [[]]
      sequenceAList (c:cs) = (:) <$> c <*> sequenceAList cs
      

      对于单个项目sequenceA ["def"] 因此等价于:

      sequenceA ["def"] = (:) <$> "def" <*> [[]]
      

      因此,它获取"def"Characters 'd''e''f' 的所有元素,然后将其与列表[[]] 的所有元素组合在一起(仅[]),因此产生"d""e""f"

      那么对于sequenceA ["c", "def"],它等价于:

      sequenceA ["c", "def"] = (:) <$> "c" <*> ["d", "e", "f"]
      

      因此产生:["cd", "ce", "cf"],最后是:

      sequenceA ["ab", "c", "def"] = (:) <$> "ab" <*> ["cd", "ce", "cf"]
      

      将产生:

      sequenceA ["ab", "c", "def"] = ["acd", "ace", "acf", "bcd", "bce", "bcf"]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-09
        • 1970-01-01
        • 1970-01-01
        • 2014-06-23
        • 2019-04-21
        • 2015-11-12
        • 2023-03-11
        相关资源
        最近更新 更多