打印集合的所有子集

时间:2020-01-19 16:04:31

标签: java arrays

我需要编写一个递归函数,该函数接收一个数字并打印从1到n的所有子组。 我不在乎订单。

例如,如果number = 3 我需要输出:

{}
{1}
{2}
{3}
{1,2}
{1,3}
{2,3}
{1,2,3}

但是我的代码给出了:

{1,2,3}
{2,3}
{3}

这是我的代码,我叫方法subGroups(3);

    public static void subGroups(int num) {
        int[] ar = new int[num];
        subGroups(ar, 1, num);
    }

    private static int[] insertToArr(int num, int[] arr) {
        if (num == 0)
            return arr;
        arr[num - 1] = num;
        return insertToArr(num - 1, arr);
    }

    private static void subGroups(int[] arr, int start, int end) {
        if (end <= 0 || start > arr.length)
            return;
        else if (start > end)
            subGroups(arr, start, end - 1);
        else {
            if (start != 0) {
                System.out.print("{");

                printAll(start, end);
                System.out.println("}");
            }
            subGroups(arr, start + 1, end);
        }

    }

    // prints all in in one line recursive
    private static void printAll(int start, int end) {
        if (start < end) {
            System.out.print(start + ",");
            printAll(start + 1, end);
        } else {
            System.out.print(start);
        }

    }

如何获得请求的结果?

3 个答案:

答案 0 :(得分:0)

如果(start > end)为true,则递归调用subGroups(arr, start, end-1)也是如此,递归将沿着该路径继续进行,直到end太小为止。

所以这里的东西需要改变。考虑到您永远都不会重设startend

答案 1 :(得分:0)

一些提示和下面的代码框架:arr应该用作所找到子集的累加器。它的初始大小为0,每当将元素添加到当前子集中时,大小就会增加。

初始呼叫应为:

int[] arr = new int[0];
subGroups(arr, 1, num);

到目前为止,您已经选择了0个元素,仍然需要选择元素{1,...,num}的子集。

函数subGroups应该是:

/*
 * generates all subsets of set {start,...,end} , union "arr"
 */
private static void subGroups(int[] arr, int start, int end) {
  //terminal condition: print the array
  if (start>end) {
    print(arr);
  }
  else {
    //here we have 2 cases: either element "start" is part of the subset, or it isn't

    // case 1: "start" is not part of the subset
    // so "arr" is unchanged
    subGroups(arr, start+1, end);

    // case 2: "start" is part of the subset
    // TODO: create another array, containing all elements of "arr", and "start"
    int[] arrWithStart=copyAndInsert(arr, start);
    subGroups(arrWithStart, start+1, end);
  }
}

private static void print(int[] arr) {
  // TODO code here
}

/*
 * copy and insert:
 * it should create a new array, with length=arr.length+1,
 * containing all elements of array "arr", and also "element"
 */
static int[] copyAndInsert(int[] arr, int element) {
  // TODO code here
}

答案 2 :(得分:-1)

这应该工作,看看如何将其移植到阵列上。

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.IntStream;

import static java.util.Collections.emptySet;
import static java.util.stream.Collectors.toList;

public class Main {
    public static void powerset(int n) {
        System.out.println(
                powerset(IntStream.rangeClosed(1, n).boxed().collect(toList()))
        );
    }

    public static Set<Set<Integer>> powerset(List<Integer> set) {
        if (set.isEmpty()) {
            Set<Set<Integer>> result = new HashSet();
            result.add(emptySet());
            return result ;
        } else {
            Integer element = set.remove(0);
            Set<Set<Integer>> pSetN_1 = powerset(set);

            Set<Set<Integer>> pSet_N= new HashSet();
            pSet_N.addAll(pSetN_1);

            for (Set<Integer> s : pSetN_1) {
                Set<Integer> ss = new HashSet(s);
                ss.add(element);
                pSet_N.add(ss);
            }
            return pSet_N;
        }
    }

    public static void main(String[] args) throws Exception {
        powerset(3); // [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
    }
}

顺便说一句,您正在计算幂集,即一组集合的所有子集(不是组)的集合