从列表中选择项目以求和
我有一个包含数值的项目列表,我需要使用这些项目求和。我需要你的帮助来构建这样的算法。下面是一个用 C# 编写的示例,描述了我的问题:
int sum = 21;
List<Item> list = new List<Item>();
list.Add(new Item() { Id = Guid.NewGuid(), Value = 3 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 5 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 12 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 3 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 2 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 7 });
List<Item> result = // the items in the list that has the defined sum.
注意:我对结果中的项目数量没有限制。
I have a list of items that has numeric values and I need to achieve a sum using these items. I need your help to build such an algorithm. Below, there is a sample that describes my problem, written in C#:
int sum = 21;
List<Item> list = new List<Item>();
list.Add(new Item() { Id = Guid.NewGuid(), Value = 3 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 5 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 12 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 3 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 2 });
list.Add(new Item() { Id = Guid.NewGuid(), Value = 7 });
List<Item> result = // the items in the list that has the defined sum.
Note: I have no constraint on the number of items in the result.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这称为子集和问题,被认为是一个难题计算机科学。并不像“难以做到”那么难,而是很难快速——你可以轻松地编写一个算法来做到这一点,但对于相当大的输入,这很容易需要数十亿年。
如果您对仅适用于小输入的缓慢解决方案感到满意,请尝试如下操作:
生成输入列表的所有子集。
对于每个子集,计算该子集中的项目总和。
返回总和匹配的第一个子集。
这是一个返回所有子集的方法(实际上是子序列,因为它维护项目的顺序,尽管在您的情况下这没有什么区别):
所以您现在可以编写类似这样的内容...
This is called the Subset sum problem and is considered a hard problem in computer science. Not hard as in hard to do, but hard to do fast — you can easily write an algorithm to do it, but for sizable inputs it will easily take billions of years.
If you are happy with a slow solution that is only practicable for small inputs, try something like this:
Generate all subsets of the input list.
For each subset, calculate the sum of the items in that subset.
Return the first subset for which the sum matches.
Here is a method that returns all subsets (actually subsequences because it maintains the order of items, although in your case this makes no difference):
So you can now write something like this...
这就是所谓的子集和问题,经过修改 - 你不想达到零,而是达到一个特定的数字。
以下是 Wiki 对此的说法 - http://en.wikipedia.org/wiki/Subset_sum_problem。
您可能会根据您对该领域的了解想到一些优化。例如,如果最大数+最小数大于总和->最高的数字永远不会被使用,你可以排除它(并尝试对新的最高数字进行相同的操作..)。
我记得按照塞缪尔的建议做了 - 递归方式,这并没有那么糟糕,(但当然总是存在 stackoverflow 问题......)。
That's called the subset sum problem, with the modification - that you don't want to get to zero, but to a specific number.
Here's what Wiki has to say about it - http://en.wikipedia.org/wiki/Subset_sum_problem.
You may think of some optimizations according to your knowledge of the domain. For example if the highest number + the lowest number are greater than the sum -> the highest number will never be used, and you can rule it out (and try the same for the new highest number..).
I remember doing it as Samuel suggested - the recursive way, which wasn't that terrible, (but of course there's always the stackoverflow issue...).
递归,添加元素直到 A) 你达到总和或 B) 你得到太多,如果 A 你完成了,如果 B 你改变元素尝试所有可能的配置。如果当前元素已经大于最后一个超过总和的元素,则可能禁止系统添加元素
recursive, add elements until A) you achieve the sum or B) you get too much, if A you're done, if B you change the elements trying all possible configurations. Maybe prohibit the system to add an element if the current element is already bigger than the last element that went over the sum
我不太确定你在这里追求的是哪一个太阳。如果您想要合并所有值的总和,请使用以下代码:
如果您想要具有特定值的所有元素,请使用以下代码:
I'm not exactly sure which sun you are after here. If you want the sum of all values combines, use this code:
If you want all elements that has a specific value, use this code: