C# 如何在数组中找到等于10的数字子集?

C# 如何在数组中找到等于10的数字子集?,c#,C#,我想求相邻数的所有子集的和 所以如果这个集合是6125 我想找到你的总数 6 1 2 2 5 6 1 2 2 1 2 2 5 6 1 2 1 2 2 2 2 5 6 1 1 2 2 2 2 5 所以我想找到的不是2个数字的所有子集,而是更多的示例输入:612256->6+2+2=10或1+2+2+5=10并打印它们 using System; class Subset { static void Main() {

我想求相邻数的所有子集的和

所以如果这个集合是6125 我想找到你的总数

6 1 2 2 5
6 1 2 2 
1 2 2 5
6 1 2
1 2 2
2 2 5
6 1
1 2
2 2
2 5
所以我想找到的不是2个数字的所有子集,而是更多的示例输入:612256->6+2+2=10或1+2+2+5=10并打印它们

   using System;
    class Subset
    {
        static void Main()
        {
            string[] num = Console.ReadLine().Split(' ');
            int[] number = new int[num.Length];

            for (int a = 0; a < 5; a++)
            {
                number[a] = Convert.ToInt32(num[a]);
            }

            int sum;
            bool found = false;


            for (int i = 0; i < 5; i++)
            {
                sum = 0;
                for (int j = i; j < 5; j++)
                {

                    sum = sum + number[j];
                    if (sum == 10)
                    {

                        found = true;

                        for (int k = i; k < j; k++)
                        {
                            Console.Write("{0} + ", number[k]);
                        }
                        Console.Write(number[j]);
                        Console.Write(" = 10\n");
                    }
                }
            }
            if (found == false)
            {
                Console.WriteLine("no zero subset\n\n");
            }
        }
    }

这与子集和问题非常相似。要想真正找到一个组合,它可以加上十个甚至所有的组合,你必须测试所有的组合。我不确定您是想要任意大小的组合,还是只想要两个数字。您给出的示例仅涉及两个数字加起来等于10的示例,这可以通过检查所有对来轻松完成

for (int i = 1; i < numbers.Length; i++)
    for (int j = 0, j < i; j++)
        if (numbers[i] + numbers[j] == 10)
        {
            Console.WriteLine("{0} + {1} = 10", numbers[i], numbers[j];
            return;
        }

Console.WriteLine("no subset that sums up to 10");
这个方法首先检查我们是否到达最后一个元素。在这种情况下,我们有两种简单的情况需要考虑:我们想要达到的和是0,所以我们不取元素,或者我们想要达到的和等于最后一个元素,在这种情况下我们取它。否则,就没有有效的解决方案。 在所有其他情况下,我们只是将分支分为两条路径,要么将元素放入子集中,要么不将元素放入子集中

该算法将以指数时间运行,以数字量作为输入。你可以通过记忆来加快速度。您可以创建一个巨大的表,保存每对startIndex,并对结果值求和。这样你就可以确信你永远不会对同一件事进行两次评估。查阅动态规划以了解更多关于这方面的信息


我上面描述的方法仅在子集存在时返回。要实际查找子集,还必须传回已添加到子集的元素的索引。我不会解决这个问题,因为这会让事情变得更复杂。如果在动态规划方法中使用表格,还可以使用一些回溯技术在线性时间内找到正确的索引。

如果所有元素都是非负的,则可以在OkN中进行此操作,即数组中严格正的元素数乘以目标数。
bool SubsetSum(int[] numbers, int startIndex, int sum)
{
    if (startIndex == numbers.Length - 1) // base case, only one element to consider
        return numbers[startIndex] == sum || sum = 0;

    return SubsetSum(numbers, startIndex + 1, sum)                       // don't take the current element
        || SubsetSum(numbers, startIndex + 1, sum - numbers[startIndex]; // take the current element
}