如何找到所有子元素,它是元素的总和等于一个常数?

时间:2016-10-19 21:53:40

标签: c# combinations subset-sum

我需要通过对其元素求和来找到所有数字子集以获得数字 N 。我不知道如何解决这种组合问题。在这种组合中,顺序对不同的数字很重要。

数字 N = 4

的示例
1 + 1 + 1 + 1
2 + 1 + 1
1 + 2 + 1
1 + 1 + 2
2 + 2
3 + 1
1 + 3

零对我来说并不重要。那么如何才能将这样的数字集合作为一个精确数字的数组呢?

2 个答案:

答案 0 :(得分:1)

您要查找的内容称为整数compositions,或已订购partitions

组合可以递归生成(按字典顺序,如果我没有记错的话),如下所示:

public static IEnumerable<List<int>> Compositions(int n)
{
    if (n < 0)
        throw new ArgumentOutOfRangeException(nameof(n));

    return GenerateCompositions(n, new List<int>());
}

private static IEnumerable<List<int>> GenerateCompositions(int n, List<int> comp)
{
    if (n == 0)
    {
        yield return new List<int>(comp); // important: must make a copy here
    }
    else
    {
        for (int k = 1; k <= n; k++)
        {
            comp.Add(k);

            foreach (var c in GenerateCompositions(n - k, comp)) 
                yield return c;

            comp.RemoveAt(comp.Count - 1);
        }
    }
}

未经测试!这是从Python实现转录而来的。如果有人想要更正或更新代码用更加惯用的C#,请随意。

另外,as @aah notedn的作文数量为2^(n-1),因此即使是适度n,这也会变得难以处理。

答案 1 :(得分:0)

如果顺序无关紧要,则只有2 ^(N-1)种可能性。 (你的例子没有2 + 2或4)

然后,您可以通过其二进制表示来表示任何序列。为了生成,想象连续N 1,所以有N-1&#34;空格&#34;它们之间。选择任何空格子集,您可以合并通过所选空间相邻的任何1。您可以通过展开任何此类序列并插入这些空格来验证这是否为1-1。