从项目的给予列表创建子列表列表、项目

2023-09-11 06:11:33 作者:№.未灬晟哖の丶尛孩

我会说:第一,以下问题不做​​作业的目的甚至,因为我已经完成软件工程师在几个月前。反正今天我正在和一个朋友问我这个陌生的排序问题。

I would say first that the following question is not for homework purpose even because i've finish software engineer a few months ago. Anyway today I was working and one friend ask to me this strange sorting problem.

我有1000行,每行重新present数字的名单,我想创建10分列出了每个有从主列表中的号码的类似总和。我该怎么办呢?

"I have a List with 1000 rows, each row represent a number, and I want to create 10 sub lists each have a similar summation of the numbers from the main list. How can I do that?"

例如我已经通过5,4,3,2和1。这很简单构成的主列表,我创建了两个子列表 之一,5和3个其他与4,2和1每个列表是相似的结果:8的第7第二。

For example I've the main list composed by 5,4,3,2 and 1. It's simple, I create two sub lists one with 5 and 3 the other with 4,2 and 1 the result of each list it's similar: 8 for the first 7 for the second.

我无法算出它的算法,即使知道它的简单,但我想的东西。

I can't figure it out the algorithm even if know it's simple but I'm missing something.

推荐答案

A 是输入数组。我会认为这是升序排列。

Let A be the input array. I'll assume it is sorted ascending.

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

M [I] 是子列表的数量发现的到目前为止有一笔相等于

Let M[i] be the number of sublist found so far to have sum equal to i.

启动仅 M [0] = 1 ,因为有一个列表,拥有和等于零,即空表。

Starts with only M[0] = 1 because there is one list with has sum equals zero, that is the empty list.

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

再从列表中每个项目 A 一个接一个。 当考虑更新的方法,你必须组成每个总和的清单数 你刚才拿的项目都可以使用。

Then take each item from the list A one-by-one. Update the number of ways you have to compose a list of each sum when considering that the item you just take can be used.

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,你应该停止算法。 此外,修改记在列表中的项目才能够得到实际的名单底!

When you found any M[j] which reach 10 during that, you should stop the algorithm. Also, modify to remember the items in the list to be able to get the actual list at the end!

注:

您可以使用的稀疏的再presentation为 M 这类似于那些背包和子集和问题。 也许你会发现很多更好的算法阅读这些。 You can use sparse representation for M This is similar to those Knapsack and subset sum problems. Perhaps you might find many better algorithms reading on those.

下面是一个工作code在Python:

Here is a working code in 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]

取的跨pretation M [11] = 3 在最后的例子。 它意味着有3子列表与总和等于11。 如果您跟踪进度,你可以看到子列表的 {2,3,6},{3,8},{11}

Take the interpretation of M[11] = 3 at the end for example; it means there are 3 sublists with sum equals 11. If you trace the progress, you can see the sublists are {2,3,6},{3,8},{11}.

要考虑的事实,你让10子列表具有的类似于的总和。不只是完全相同的总和。您可能希望从改变终止条件终止如有M [J]> = 10到终止,如果金额(M [J:J + 3])> = 10。或者类似的东西。

To account for the fact that you allow the 10 sublists to have similar sum. Not just exactly the same sum. You might want to change termination condition from "terminate if any M[j] >= 10" to "terminate if sum(M[j:j+3]) >= 10" or something like that.