简体   繁体   中英

Print all subsets in an array that equal to a given sum recursively

I have to write a code with a two methods that takes an array (non-negative) and a value sum as parameters. I have to use the methods:


public static void printSubsetSums(int[] arr, int sum) {

}

public static void printSubsetSums(int[] arr, int sum, int i, String acc) 
{

}

We are not allowed to add methods or any more parameters for the current methods. I did something similar that just prints the number of subsets that are from a given array according to a sum. but i'm having a hard time to change it to do this task... my array is limited to the length of 5.

ecxample: "Enter 5 numbers to array" input:1 2 3 4 5 "Enter a number into sum" input:8 3

why 3? (3,5), (1,3,4), (1,2,5)

Thank you for your help!!!

Here is a recursive approach for solving this problem:

    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]);
    }

Explanation:

First, you input your integer array and desired sum into the printSubsetSums(int[] arr, int sum) method that calls the helper method ( printSubsetSums(int[] arr, int sum, int i, String acc) ), where i is arr 's index and acc is the output for how the sum was reached.

if (i == arr.length) { return; } if (i == arr.length) { return; } acts as the base case to exit out of the recursive method ( i is out of bounds).

Notice that we have two recursive calls ( printSubsetSums(arr, sum, i + 1, acc) and printSubsetSums(arr, sum - arr[i], i + 1, acc+" "+arr[i]) ). The first acts if the current number would not work in order to reach the sum and thus i is incremented to "try again" with the next number in arr . The second option is that the current number will work, and so you move on to the next index whilst accounting for the current number (subtracting it from sum in order to eventually reach 0 [when we know that the numbers selected did add up to 10] and adding it to acc ).

Finally, we print acc when the sum is 0. We also set acc = "" and avoid printing when "".equals(acc) in order to avoid counting the same answer multiple times.

Result:

Example Input:

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

Example Output:

 3 5
 1 3 4
 1 2 5

I think you have to take as input an array of numbers, and give the sum and number of integers that can be equal to this sum

In your example:

Enter 5 numbers to array: 1 2 3 4 5

Enter a number into sum: 8 3 ( here i think 3 means it wants only 3 numbers to form 8, like 1 2 5 and 2 3 5 .. etc )

You can do it in this way:

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();
        }
    }

}

The requirement imposed in the question is a little difficult to interpret. However, I have coded to fulfill your use case.

The approach which I have used is the following:

  1. Find all the possible subset of the given array using the bit-manipulation method.

  2. Check if the sum of the subset is equal to the given sum. If it is yes, then print it on the console.

Check the snippet below for more clarity.

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);
    }
}

Input1 to the program

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

Output1 by the program

1 3 4 
1 2 5 
3 5

Input2 to the program

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

Output2 by the program

There is no subset possible for the sum = 20

I hope this helps.

Suggest an algorithm or approach to print elements/integers of an array, given the sums of all subsets.

For example, given sums of subset; {0,1,2,3} --> values of the array would be, arr[] = {1,2}, whose subsets would be {{} -> sum is '0', {1} -> sum is '1', {2} -> sum is 2, {1,2} -> sum is '3'}; Note: All values in the given array are positive N>=0;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM