使用给定的一组数字将所有可能的组合求和成给定的数字

时间:2019-05-17 04:41:01

标签: java algorithm combinations

找到解决方案

Finding all possible combinations of numbers to reach a given sum

问题

在上述解决方案中,可以使用给定的一组数字求和得出给定的值,而无需重复相同的数字来获得所有组合。

如何操作以下算法以获取所有可能的组合,包括重复的数字以求和成给定值?

import java.util.ArrayList;
import java.util.Arrays;

class SumSet
{
    static void sum_up_recursive(ArrayList<Integer> numbers, int target, ArrayList<Integer> partial)
    {
        int s = 0;
        for (int x : partial)
            s += x;
        if (s == target)
            System.out.println("sum(" + Arrays.toString(partial.toArray()) + ")=" + target);
        if (s >= target)
            return;
        for (int i = 0; i < numbers.size(); i++)
        {
            ArrayList<Integer> remaining = new ArrayList<Integer>();
            int n = numbers.get(i);
            for (int j = i + 1; j < numbers.size(); j++)
                remaining.add(numbers.get(j));
            ArrayList<Integer> partial_rec = new ArrayList<Integer>(partial);
            partial_rec.add(n);
            sum_up_recursive(remaining, target, partial_rec);
        }
    }

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

    public static void main(String args[])
    {
        Integer[] numbers = { 3, 9, 8, 4, 5, 7, 10 };
        int target = 15;
        sum_up(new ArrayList<Integer>(Arrays.asList(numbers)), target);
    }
}

并且输出中不应包含排列,而只能包含组合

示例

15可以由3 + 3 + 3 + 3 + 39 + 3 + 3求和。但是输出应仅包含以下各项之一,9 + 3 + 33 + 9 + 33 + 3 + 9

1 个答案:

答案 0 :(得分:0)

只需删除正在进行的工作即可获得剩余的数字,并在递归时传回原始数字。我测试了以下内容。

    import java.util.ArrayList;
    import java.util.Arrays;

    public class SumSet
    {
        static void sum_up_recursive(ArrayList<Integer> numbers, int target, ArrayList<Integer> partial)
        {
            int s = 0;
            for (int x : partial)
                s += x;
            if (s == target)
                System.out.println("sum(" + Arrays.toString(partial.toArray()) + ")=" + target);
            if (s >= target)
                return;
            for (int i = 0; i < numbers.size(); i++)
            {
                int n = numbers.get(i);
                ArrayList<Integer> partial_rec = new ArrayList<Integer>(partial);
                partial_rec.add(n);
                sum_up_recursive(numbers, target, partial_rec);
            }
        }

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

        public static void main(String args[])
        {
            Integer[] numbers = { 3, 9, 8, 4, 5, 7, 10 };
            int target = 15;
            sum_up(new ArrayList<Integer>(Arrays.asList(numbers)), target);
        }
    }
and the results allow for repetition as you wished:

    sum([3, 9, 3])=15
    sum([3, 8, 4])=15
    sum([3, 4, 3, 5])=15
    sum([3, 4, 8])=15
    sum([3, 4, 4, 4])=15
    sum([3, 4, 5, 3])=15
    sum([3, 5, 3, 4])=15
    sum([3, 5, 4, 3])=15
    sum([3, 5, 7])=15
    sum([3, 7, 5])=15
    sum([9, 3, 3])=15
    sum([8, 3, 4])=15
    sum([8, 4, 3])=15
    sum([8, 7])=15
    sum([4, 3, 3, 5])=15
    sum([4, 3, 8])=15
    sum([4, 3, 4, 4])=15
    sum([4, 3, 5, 3])=15
    sum([4, 8, 3])=15
    sum([4, 4, 3, 4])=15
    sum([4, 4, 4, 3])=15
    sum([4, 4, 7])=15
    sum([4, 5, 3, 3])=15
    sum([4, 7, 4])=15
    sum([5, 3, 3, 4])=15
    sum([5, 3, 4, 3])=15
    sum([5, 3, 7])=15
    sum([5, 4, 3, 3])=15
    sum([5, 5, 5])=15
    sum([5, 7, 3])=15
    sum([5, 10])=15
    sum([7, 3, 5])=15
    sum([7, 8])=15
    sum([7, 4, 4])=15
    sum([7, 5, 3])=15
    sum([10, 5])=15

修订: 上面包含排列(相对于组合)。如果也想避免以其他方式获得[3,5,7]和[3,7,5]以及同一组合的其他4种方法,则可以坚持数字不减少(或等效地,不增加)[如果您想成为数学专家,则可以添加“单调”一词。这可以通过在递归函数顶部进行快速检查来完成,方法是使用一种根据(Java) Check array for increasing elements的已接受答案改编的小方法。  修订后的版本变为:

import java.util.ArrayList;
import java.util.Arrays;

public class SumSet
{
    public static boolean isNondecreasing(ArrayList<Integer> arr)
{
    for(int i=1; i<arr.size();i++)
    {
        if(arr.get(i-1)>arr.get(i))
            return false;
    }
    return true;
 }

    static void sum_up_recursive(ArrayList<Integer> numbers, int target, ArrayList<Integer> partial)
    {
        int s = 0;
        if (!(isNondecreasing(partial))){
            return;
        }
        for (int x : partial)
            s += x;
        if (s == target)
            System.out.println("sum(" + Arrays.toString(partial.toArray()) + ")=" + target);
        if (s >= target)
            return;
        for (int i = 0; i < numbers.size(); i++)
        {
            int n = numbers.get(i);
            ArrayList<Integer> partial_rec = new ArrayList<Integer>(partial);
            partial_rec.add(n);
            sum_up_recursive(numbers, target, partial_rec);
        }
    }

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

    public static void main(String args[])
    {
        Integer[] numbers = { 3, 9, 8, 4, 5, 7, 10 };
        int target = 15;
        sum_up(new ArrayList<Integer>(Arrays.asList(numbers)), target);
    }
}

,输出为简短代码:

sum([3, 3, 3, 3, 3])=15
sum([3, 3, 9])=15
sum([3, 3, 4, 5])=15
sum([3, 4, 8])=15
sum([3, 4, 4, 4])=15
sum([3, 5, 7])=15
sum([4, 4, 7])=15
sum([5, 5, 5])=15
sum([5, 10])=15
sum([7, 8])=15