打印一组的所有子集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了打印一组的所有子集相关的知识,希望对你有一定的参考价值。
我需要编写一个recursive函数,该函数接收一个数字并打印从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);
如何获得请求的结果?
答案
这应该工作,请参阅如何将其移植到数组。
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]]
顺便说一句,您正在计算幂集,即集合的所有子集(不是组)的集合
另一答案
如果(start > end)
为true,则递归调用subGroups(arr, start, end-1)
也将为true,并且递归将沿着该路径继续进行,直到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
以上是关于打印一组的所有子集的主要内容,如果未能解决你的问题,请参考以下文章