递归打印等于给定总和的数组中的所有子集

时间:2020-06-01 19:06:51

标签: java arrays recursion subset subset-sum

我必须用两种方法编写代码,这两种方法都需要一个数组(非负数)和一个值和作为参数。 我必须使用以下方法:


func logout() {
    navigationController?.popViewController(animated: true)
}

我们不允许为当前方法添加方法或任何其他参数。 我做了类似的事情,只是根据总和来打印给定数组的子集数量。但是我很难改变它来执行此任务... 我的数组长度限制为5。

示例: “输入5个要排列的数字” 输入:1 2 3 4 5 “输入数字求和” 输入8 3

为什么3? (3,5),(1,3,4),(1,2,5)

谢谢您的帮助!

4 个答案:

答案 0 :(得分:0)

我认为您必须将一个数字数组作为输入,并给出可以等于该和的整数的总和和数量

在您的示例中:

输入5个要排列的数字:1 2 3 4 5

输入一个数字作为总和:8 3(在这里我认为3表示它只希望将3个数字形成8,例如 1 2 5 2 3 5 ..等)

您可以通过以下方式做到这一点:

public static void printSubsetSums(int[] arr, int sum, int i) {
    // getting all possible sub arrays of a lentgh of i 
    ArrayList<int[]> subarrays = new ArrayList<int[]>();
    ArrayList<Integer> array = new ArrayList<Integer>();


    int arrSize = arr.length;
    for (int startPoint = 0; startPoint <arrSize ; startPoint++) {
        for (int grps = startPoint; grps <=arrSize ; grps++) {
            for (int j = startPoint ; j < grps ; j++) {
                int element = arr[j];
                array.add(element);
            }
            int[] tab = new int[array.size()];
            int x = 0;
            for(int n : array) {
                tab[x] = n;
                x++;
            }
            subarrays.add(tab);
            array.clear();

        }
    }
    // calculating the sum of each one of these arrays
    // print the ones that their sum equal the sum given with argument
    for(int[] al : subarrays) {
        if (al.length==3) {
            int sum2 = 0;
            for (int n : al) {
                sum2 = sum2 + n;
                System.out.print(n);
            }
            System.out.print(" = "+sum2);
            if(sum2==sum) { System.out.print(" that is a desired sum"); }
            System.out.println();
        }
    }

}

答案 1 :(得分:0)

问题中提出的要求有点难以解释。但是,我已编写代码来满足您的用例。

我使用的方法如下:

  1. 使用位处理方法查找给定数组的所有可能子集。

  2. 检查子集的总和是否等于给定的总和。如果是,则在控制台上将其打印。

请查看下面的代码段,以获取更多信息。

import java.util.Scanner;

public class SubsetSum {
    public static void printSubsetSums(int[] arr, int sum) {
        printSubsetSums(arr, sum, 0, "NotNeeded");
    }

    public static void printSubsetSums(int[] arr, int sum, int i, String acc) {
        // variable 'i' and 'acc' are not getting used anywhere.
        // Have added because you want to make the same syntax for the function.
        boolean isAnySubsetPossible = false;
        int n = arr.length;

        // Run a loop from 0 to 2^n
        for (int p = 0; p < (1 << n); p++) {
            int[] temporaryArray = new int[n];
            int k = 0;
            int m = 1; // m is used to check set bit in binary representation.
            // Print current subset
            for (int j = 0; j < n; j++) {
                if ((p & m) > 0) {
                    temporaryArray[k++] = arr[j];
                }
                m = m << 1;
            }

            int localSum = 0;
            for (int temp : temporaryArray) {
                localSum += temp;
            }
            if (localSum == sum) { // check if the sum is equal to the desired sum
                isAnySubsetPossible = true;
                for (int item : temporaryArray) {
                    if (item > 0) {
                        System.out.print(item + " ");
                    }
                }
                // print a new line so that next subset starts from new line
                System.out.println();
            }
        }
        if (!isAnySubsetPossible) {
            System.out.println("There is no subset possible for the sum = " + 20);
        }
    }

    public static void main(String[] args) {
        Scanner myScanner = new Scanner(System.in);
        System.out.println("Enter 5 numbers into array");
        int[] myArr = new int[5];
        for (int i = 0; i < myArr.length; i++) {
            myArr[i] = myScanner.nextInt();
        }
        System.out.println("Enter a number into sum");
        int sum = myScanner.nextInt();
        printSubsetSums(myArr, sum);
    }
}

向程序输入1

Enter 5 numbers into array
1 2 3 4 5
Enter a number into sum
8

该程序的Output1

1 3 4 
1 2 5 
3 5

输入2到程序

Enter 5 numbers into array
1 2 3 4 5
Enter a number into sum
20

该程序的Output2

There is no subset possible for the sum = 20

我希望这会有所帮助。

答案 2 :(得分:0)

这是解决此问题的一种递归方法:

    public static void printSubsetSums(int[] arr, int sum) {
        printSubsetSums(arr, sum, 0, "");
    }

    public static void printSubsetSums(int[] arr, int sum, int i, String acc) 
    {
        if (sum == 0 && !"".equals(acc)) {
            System.out.println(acc);
            acc = "";
        }
        if (i == arr.length) {
            return;
        }
        printSubsetSums(arr, sum, i + 1, acc);
        printSubsetSums(arr, sum - arr[i], i + 1, acc+" "+arr[i]);
    }

说明:

首先,将整数数组和所需的和输入到调用帮助程序方法(printSubsetSums(int[] arr, int sum))的printSubsetSums(int[] arr, int sum, int i, String acc)方法中,其中iarr的索引, acc是 输出如何得出总和。

if (i == arr.length) { return; }是退出递归方法的基本情况(i超出范围)。

请注意,我们有两个递归调用(printSubsetSums(arr, sum, i + 1, acc)printSubsetSums(arr, sum - arr[i], i + 1, acc+" "+arr[i]))。如果当前数字将不起作用以达到总和,则第一个操作会发生,因此i会增加arr中的下一个数字,以“重试”。第二个选择是当前数字将起作用,因此您在考虑当前数字的同时转到下一个索引(从sum中减去它以最终达到0 [当我们知道所选数字已加至10],然后将其添加到acc)。

最后,我们在acc为0时打印sum。我们还设置acc = ""并避免在"".equals(acc)时打印,以避免多次计算相同的答案。

结果:

示例输入:

printSubsetSums(new int[]{1,2,3,4,5}, 8)

示例输出:

 3 5
 1 3 4
 1 2 5

答案 3 :(得分:0)

在给定所有子集的总和的情况下,建议一种算法或方法来打印数组的元素/整数。

例如,给定子集的总和; {0,1,2,3}->数组的值为arr [] = {1,2},其子集为{{}-> sum为'0',{1}-> sum为'1',{2}->和为2,{1,2}->和为'3'}; 注意:给定数组中的所有值均为正N> = 0;