繁体   English   中英

打印集合的所有子集

[英]Print all subsets of a set

我需要编写一个递归函数来接收一个数字并打印从 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);
        }

    }

我如何获得请求的结果?

如果(start > end)为真,那么递归调用subGroups(arr, start, end-1)也是如此,并且递归将沿着这条路径继续,直到end太小。

所以这里需要改变一些东西。 考虑到您从未重置startend

一些提示,以及下面的代码框架: 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
}

这应该可以工作,看看如何将其移植到数组。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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