【问题标题】:Subset of length k?长度为 k 的子集?
【发布时间】:2019-10-07 03:28:36
【问题描述】:

以下代码以优化的方式工作,我想理解它但失败了。我理解第一行,但第二行我迷路了。如果有人可以用 C 或 Python 来解释它,那将是很棒的,甚至是一般的想法。谢谢

combinations :: Int -> [a] -> [[a]]
combinations k xs = combinations' (length xs) k xs
  where combinations' n k' l@(y:ys) 
    | k' == 0   = [[]] 
    | k' >= n   = [l] 
    | null l    = [] 
    | otherwise = map (y :) (combinations' (n - 1) (k' - 1) ys) 

【问题讨论】:

    标签: haskell


    【解决方案1】:

    Python 中的等价物。请注意,这在 CPython 中非常糟糕,因为递归在那里实现得非常糟糕,并且在所有 Python 风格中都非常糟糕,因为列表的构造方式不同(1: [2, 3, 4]) 在 Haskell 中很简单,但在 Python 中做同样的事情需要一些 @ 987654323@ 或丑陋的[1] + [2,3,4] 东西)

    from typing import TypeVar, List
    
    A = TypeVar('A')
    def combinations(k: int, xs: List[A]) -> List[List[A]]:
        def helper(n: int, k2: int, lst: List[A]) -> List[List[A]]:
            # base cases
            if k2 == 0: return [[]]     # if the requested subsequence length is zero
            elif k2 >= n: return [lst]  # if the requested subsequence length is longer than the whole sequence
            elif not lst: return []     # if the sequence itself is empty
    
            y, ys = lst[0], lst[1:]
            return [[y] + rest for rest in helper(n-1, k2-1, ys)]
    
        return helper(len(xs), k, xs)
    

    请注意,Haskell 中过度使用守卫让我觉得有些丑陋。我可能会改写为:

    combinations :: Int -> [a] -> [[a]]
    combinations k xs = combinations' (length xs) k xs
      where
        combinations' _ 0  _  = [[]]
        combinations' _ _  [] = []
        combinations' n k' l@(y:ys)
          | k' >= n           = [l]
          | otherwise         = map (y :) (combinations' (n - 1) (k' - 1) ys) 
    

    【讨论】:

    【解决方案2】:

    Khuldraeseth na'Barya in this question 提供了一种与模式匹配等效的简单替代方法:

    subsetsOfLength 0 _  = [[]]
    subsetsOfLength _ [] = []
    subsetsOfLength n (x:xs) = map (x:) (subsetsOfLength (n-1) xs) ++ subsetsOfLength n xs
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-17
      • 2021-10-01
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多