c# - 从列表中选择项目以求和

标签 c# .net algorithm list combinations

我有一个包含数值的项目列表,我需要使用这些项目求和。我需要你的帮助来构建这样的算法。下面是一个用 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.

注意:我对结果中的项目数没有限制。

最佳答案

这叫做 Subset sum problem 被认为是计算机科学中的难题。不像难做那样难,但难 — 您可以轻松编写算法来完成它,但对于大量输入,它很容易需要数十亿年。

如果您对仅适用于小输入的缓慢解决方案感到满意,请尝试如下操作:

  • 生成输入列表的所有子集。

  • 对于每个子集,计算该子集中项目的总和。

  • 返回总和匹配的第一个子集。

这是一个返回所有子集的方法(实际上是子序列,因为它维护了项目的顺序,尽管在您的情况下这没有区别):

/// <summary>
/// Returns all subsequences of the input <see cref="IEnumerable&lt;T&gt;"/>.
/// </summary>
/// <param name="source">The sequence of items to generate
/// subsequences of.</param>
/// <returns>A collection containing all subsequences of the input
/// <see cref="IEnumerable&lt;T&gt;"/>.</returns>
public static IEnumerable<IEnumerable<T>> Subsequences<T>(
        this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentNullException("source");
    // Ensure that the source IEnumerable is evaluated only once
    return subsequences(source.ToArray());
}

private static IEnumerable<IEnumerable<T>> subsequences<T>(IEnumerable<T> source)
{
    if (source.Any())
    {
        foreach (var comb in subsequences(source.Skip(1)))
        {
            yield return comb;
            yield return source.Take(1).Concat(comb);
        }
    }
    else
    {
        yield return Enumerable.Empty<T>();
    }
}

所以你现在可以写这样的东西了......

var result = list.Subsequences()
                 .FirstOrDefault(ss => ss.Sum(item => item.Value) == sum);

关于c# - 从列表中选择项目以求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3750615/

相关文章:

c# - RestSharp 如何在 Https 请求中添加客户端证书? (C#)

.net - "this"的启发式和闭包好吗? (表达式树)

c# - 如何在 WCF 4.5 中使用 gzip 压缩

performance - Big-O 表示法中的计算复杂性

string - Needleman Wunsch 算法与蛮力相比如何?

序列填充数字的算法

c# - 无法确定用户的配置路径(尝试获取修订号时)

c# - 点击 Windows Phone 8 8.1 时禁用 slider 值更改

c# - VS 2010 是否允许我在 C# 中使用新的 async 和 await 关键字?

c# - 在 stimulsoft 报告中处理关系时出现错误