[英]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
太小。
所以这里需要改变一些东西。 考虑到您从未重置start
或end
。
一些提示,以及下面的代码框架: 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.