【问题标题】:Finding all possible combinations of elements in a list of integers. all elements of any of the new list have to be at least 2 apart在整数列表中查找所有可能的元素组合。任何新列表的所有元素都必须至少相隔 2
【发布时间】:2021-11-29 21:14:27
【问题描述】:

我需要一个函数,它获取一个列表作为输入,并返回所有使用最大整数数量的组合(此处为 5),其中没有 2 个相邻整数,如 2、3 或 6,7。

list0 = [0, 3, 4, 6, 10, 11, 12, 13]

all_combinations = magic_function(list0)

all_combinations 是这样的:

[[0, 3, 6, 10, 12],
 [0, 3, 6, 11, 13],
 [0, 4, 6, 10, 12],
 [0, 4, 6, 11, 13]]

这可以通过获取所有组合然后挑选出正确的组合来完成,但我不能让它占用太多内存或变慢,因为它必须处理长度不超过 98 个元素的列表。

【问题讨论】:

  • 欢迎来到Stack Overflow. 请注意这不是代码编写或辅导服务。我们可以帮助解决具体的技术问题,而不是对代码或建议的开放式请求。请编辑您的问题以显示您迄今为止尝试过的内容,以及您需要帮助的具体问题。请参阅How To Ask a Good Question 页面,详细了解如何最好地帮助我们。
  • 这其实是一个有趣的问题。
  • 我认为您缺少几个有效输出:[0, 3, 6, 10, 13], [0, 4, 6, 10, 13]
  • “告诉我如何解决这个编码问题”是off-topic for Stack Overflow。我们希望您发送honest attempt at a solution,发布该尝试,然后询问有关它的具体问题(即解释它为什么不起作用或它有什么问题)。
  • np.diffitertools.permutations 将完成工作......

标签: python list combinations


【解决方案1】:

您可以使用递归生成器函数:

def combos(d, c = []):
   if len(c) == 5:
      yield c
   else:
      for i in d:
         if not c or c[-1]+1 < i:
            yield from combos(d, c+[i])

list0 = [0, 3, 4, 6, 10, 11, 12, 13]
print(list(combos(list0)))

输出:

[[0, 3, 6, 10, 12], 
 [0, 3, 6, 10, 13], 
 [0, 3, 6, 11, 13], 
 [0, 4, 6, 10, 12], 
 [0, 4, 6, 10, 13], 
 [0, 4, 6, 11, 13]]

【讨论】:

    【解决方案2】:

    我的做法如下:

    import itertools
    
    lst = [0, 3, 4, 6, 10, 11, 12, 13] # 0 | 3 4 | 6 | 10 11 12 13
    
    chunks, chunk = [], [] # defining chunk here is actually useless
    prev = None
    for x in lst:
        if prev is None or x - prev > 1: # if jump > 1
            chunks.append(chunk := []) # insert a brand-new chunk
        chunk.append(x)
        prev = x # update the previous number
    
    def max_nonadjacents(chunk): # maximal nonadjacent sublists (given a chunk)
        if not chunk or len(chunk) % 2: # odd length is easy
            return {tuple(chunk[::2])}
        return{tuple((chunk[:i] + chunk[i+1:])[::2]) for i in range(len(chunk))}
    
    output = [list(itertools.chain.from_iterable(prod)) # flattening
                  for prod in itertools.product(*map(max_nonadjacents, chunks))]
    
    print(output)
    # [[0, 3, 6, 11, 13], [0, 3, 6, 10, 12], [0, 3, 6, 10, 13], [0, 4, 6, 11, 13], [0, 4, 6, 10, 12], [0, 4, 6, 10, 13]]
    

    我假设输入列表已排序。

    基本上,我的方法首先是认识到问题可以分成更小的部分;该列表可以分为块,其中每个块由运行整数组成; [0][3, 4][6][10, 11, 12, 13]

    然后你可以看到你可以通过从每个块中获取所有最大的非相邻列表,然后在块中获取列表的产品来获得所有可能的组合。

    代码遵循以下过程:(i) 获取 chunks,(ii) 定义一个辅助函数 max_nonadjacents,用于提取所有最大的非相邻列表,(iii) 将其应用于每个块 (map(max_nonadjacents, ...) ),然后 (iv) 取出产品。

    【讨论】:

      猜你喜欢
      • 2014-08-28
      • 1970-01-01
      • 2023-02-14
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多