仅返回给定数字列表中与目标值相加的一个子集

时间:2016-07-18 22:16:16

标签: c# subset-sum

我希望有人可以协助处理我遇到的子集和问题。我从另一个线程中获取了以下代码。理想情况下,我想要做的是有一个函数返回满足这个条件的第一个数组:" 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);
        }
    }


}

1 个答案:

答案 0 :(得分:0)

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

public List<String> getEqualsPart(List<String>[] listsToCheck) {
    if (listsToCheck.length == 0) {
        return Collections.emptyList();
    }
    int minLength = getShortesListLength(listsToCheck);
    if (minLength == 0) {
        return Collections.emptyList();
    }
    return getEqualPartsForIndex(listsToCheck, 0, minLength, new ArrayList<String>());

}

private int getShortesListLength(List<String>[] listsToCheck) {
    int min = Integer.MAX_VALUE;
    for (List<String> currentList : listsToCheck) {
        min = Math.min(min, currentList.size());
    }
    return min;
}

private List<String> getEqualPartsForIndex(List<String>[] listsToCheck, int index, int minLength,
        List<String> result) {
    if (index == minLength) {
        return result;
    }
    Set<String> setForIndex = new HashSet<>();
    Arrays.stream(listsToCheck).forEach(list -> setForIndex.add(list.get(index)));
    if (setForIndex.size() > 1) {
        return result;
    } else {
        result.add(setForIndex.iterator().next());
        return getEqualPartsForIndex(listsToCheck, index + 1, minLength, result);
    }

}`