从项目列表中创建子列表

时间:2013-06-06 14:32:03

标签: python arrays algorithm sorting numpy

我首先要说的是以下问题不是出于家庭作业,即使是因为几个月前我已经完成了软件工程师。无论如何,今天我正在工作,一位朋友问我这个奇怪的排序问题。

“我有一个包含1000行的列表,每行代表一个数字,我想创建10个子列表,每个子列表都有一个类似于主列表中数字的总和。我该怎么做?”

例如,我有由5,4,3,2和1组成的主列表。很简单,我创建了两个子列表 一个用5和3另一个用4,2和1每个列表的结果它是相似的:8用于第一个7用于第二个。

即使知道它很简单,我也无法弄清楚算法,但我遗漏了一些东西。

1 个答案:

答案 0 :(得分:3)

A成为输入数组。我会假设它按升序排序。

A = [2,3,6,8,11]

M[i]设为到目前为止的子列表数,使其总和等于i

仅从M[0] = 1开始,因为有一个列表的总和等于零,即空列表。

M = [1,0,0,...]

然后逐一列出A列表中的每个项目。 更新您在考虑时撰写每个总和列表的方式 您可以使用您刚刚拍摄的物品。

Suppose a is the new item
for each j:
    if M[j] != 0:
        M_next[j+a] = M[j+a] + M[j]

当您发现任何M[j]达到10时,您应该停止算法。 另外,修改以记住列表中的项目,以便能够在最后获得实际列表!

注意:

  • 您可以对M
  • 使用稀疏表示
  • 这类似于背包和子集和问题。 也许你可能会发现许多更好的算法阅读它们。

以下是Python中的工作代码:

A = [2,3,6,8,11]
t = sum(A)
M = [0]*(t+1)
M[0] = 1

print 'init M :',M

for a in A:
    for j in range(len(M)-1,-1,-1):
        if M[j] != 0:
            M[j+a] += M[j]
    print 'use',a,':',M

及其输出:

init M : [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 2 : [1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 3 : [1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 6 : [1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 8 : [1, 0, 1, 1, 0, 1, 1, 0, 2, 1, 1, 2, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
use 11 : [1, 0, 1, 1, 0, 1, 1, 0, 2, 1, 1, 3, 0, 2, 2, 0, 2, 2, 0, 3, 1, 1, 2, 0, 1, 1, 0, 1, 1, 0, 1]

最后以M[11] = 3的解释为例; 这意味着有3个子列表,总和等于11。 如果您跟踪进度,则可以看到子列表为{2,3,6},{3,8},{11}


考虑到您允许10个子列表具有类似总和的事实。不仅仅是完全相同的总和。您可能希望将终止条件从“终止,如果任何M [j]> = 10”更改为“终止,如果总和(M [j:j + 3])> = 10”或类似的东西。