【问题标题】:Return only one subset of a given number list that sums to a target value仅返回总和为目标值的给定数字列表的一个子集
【发布时间】:2016-07-18 22:16:15
【问题描述】:

我希望有人可以帮助解决我遇到的子集总和问题。我从另一个线程中获取了以下代码。理想情况下,我想做的是有一个函数返回满足此条件的第一个数组:“ if (s == target && partial.ToArray().Length == 7)”。 我在下面使用的代码有可能吗?换句话说,我不想要所有组合,只想要满足该条件的第一个组合。我尝试了一些东西,但我在 C# 方面的经验还不够,无法真正理解如何跳出递归或将数组返回给调用函数。任何帮助将不胜感激。

        private void button1_Click(object sender, EventArgs e)
    {

        List<int> numbers = new List<int>() { 2, 6, 6, 5, 8, 1, 3, 3, 9, 3, 6, 1, 3, 9, 1, 7, 8, 6, 8, 1, 1, 4, 4, 2, 8, 4, 5, 4, 6, 10, 1, 4, 3, 1, 2, 8, 4, 5, 9, 2, 2, 4 };
        int target = 27;
        sum_up(numbers, target);
    }

    private static void sum_up(List<int> numbers, int target)
    {
        sum_up_recursive(numbers, target, new List<int>());
    }

    private static void sum_up_recursive(List<int> numbers, int target, List<int> partial)
    {
        int s = 0;
        foreach (int x in partial) s += x;

        if (s == target && partial.ToArray().Length == 7)
            Console.WriteLine("sum(" + string.Join(",", partial.ToArray()) + ")=" + target);

        if (s >= target)
            return;

        for (int i = 0; i < numbers.Count; i++)
        {
            List<int> remaining = new List<int>();
            int n = numbers[i];
            for (int j = i + 1; j < numbers.Count; j++) remaining.Add(numbers[j]);

            List<int> partial_rec = new List<int>(partial);
            partial_rec.Add(n);
            sum_up_recursive(remaining, target, partial_rec);
        }
    }


}

【问题讨论】:

  • 你可以让sum_up_recursive在找到解决方案时返回true,在没有找到解决方案时返回false。然后,当(递归调用的)返回值为true时,您可以退出循环。
  • 那么我理解正确吗?您想找出列表中前 7 个连续数字加起来等于目标数字吗?
  • @Meloviz 差不多就是这个想法,但连续 7 次对我来说并不重要。我的愿景是,我将拥有一个包含七个数字的列表,然后我将从原始数组中删除它们,然后再次运行,直到所有数字都被分配。事实证明这很棘手

标签: c# subset-sum


【解决方案1】:

我确信有更简单的方法可以做到这一点,但要使用您的代码,我相信这是您可以做到的一种方法:

using System.Linq;
using System.Collections.Generic;

private void button1_Click(object sender, EventArgs e)
{

    List<int> numbers = new List<int>
    { 
        2, 6, 6, 5, 8, 1, 3, 3, 9, 3, 6, 1, 3, 9, 1, 7, 8, 6, 8, 1, 1,
        4, 4, 2, 8, 4, 5, 4, 6, 10, 1, 4, 3, 1, 2, 8, 4, 5, 9, 2, 2, 4 
    };
    int target = 27;
    sum_up(numbers, target);
}

private static void sum_up(List<int> numbers, int target)
{
    sum_up_recursive(numbers, target, new List<int>(), 0);
}

private static void sum_up_recursive
    (List<int> numbers, int target, List<int> @partial, int index)
{
    int s = @partial.Sum();

    if (s >= target && @partial.Count == 7)
    {
        Console.WriteLine("sum(" + string.Join(",", partial.ToArray()) + ")=" + target);
    }
    else if (s < target)
    {
        if( index + 7 > numbers.Count )
        {
            return;
        }
        else
        {
            List<int> partial_rec = numbers.GetRange(index, index + 7);
            sum_up_recursive(numbers, target, partial_rec, ++index);
        }
    }
}

【讨论】:

  • 这很好用,谢谢。我只需要弄清楚如何将这个值返回给原始函数。
  • @Majobber,如果要从sum_up_recursive 返回列表,只需将其返回值从void 更改为List&lt;int&gt;,并将Console.WriteLine(...) 替换为return numbers.GetRange(index, index + 7)。还要在调用sum_up_recursive 之前加上return
猜你喜欢
  • 2016-04-20
  • 2019-05-08
  • 1970-01-01
  • 2021-01-19
  • 2013-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
相关资源
最近更新 更多