Java 如何使用递归返回集合大小为k的所有子集?
我正在完成一项实验任务,其中我需要使用递归返回一定大小k的所有子集。函数接受集合S和该k值。我用Java做这件事;我已经看到了这个问题的答案,但它们是用C语言编写的,我正在努力建立这两种语言之间的联系 我已经编写了一个函数来使用递归查找给定集合的powerset,并了解该代码是如何工作的(如下所示)。我在为这个问题找出基本情况和递归情况方面最为困难,因此我在编写有效的代码方面没有取得任何成功。对于这个问题,我们不允许从我们已经编写的函数中创建一个powerset,然后选择正确大小的子集;我们必须更有效地做这件事Java 如何使用递归返回集合大小为k的所有子集?,java,recursion,set,Java,Recursion,Set,我正在完成一项实验任务,其中我需要使用递归返回一定大小k的所有子集。函数接受集合S和该k值。我用Java做这件事;我已经看到了这个问题的答案,但它们是用C语言编写的,我正在努力建立这两种语言之间的联系 我已经编写了一个函数来使用递归查找给定集合的powerset,并了解该代码是如何工作的(如下所示)。我在为这个问题找出基本情况和递归情况方面最为困难,因此我在编写有效的代码方面没有取得任何成功。对于这个问题,我们不允许从我们已经编写的函数中创建一个powerset,然后选择正确大小的子集;我们必须
public static Set<Set<String>> allSubsets(Set<String> s) {
Set<Set<String>> pSet = new HashSet<>();
Set<String> temp = new HashSet<>();
temp.addAll(s);
// base case
// if temp is empty set, add the empty set to the powerset
if (temp.isEmpty()) {
pSet.add(temp);
}
// recursive case
else {
Iterator<String> itr = temp.iterator();
String current = itr.next();
temp.remove(current);
Set<Set<String>> pSetTemp = allSubsets(temp);
for (Set<String> x : pSetTemp) {
pSet.add(x);
Set<String> copySubset = new HashSet<>();
copySubset.addAll(x);
copySubset.add(current);
pSet.add(copySubset);
}
}
return pSet;
}
公共静态集合所有子集(集合s){
Set pSet=new HashSet();
Set temp=new HashSet();
临时地址;
//基本情况
//如果temp为空集,请将空集添加到电源集
if(temp.isEmpty()){
pSet.add(温度);
}
//递归案例
否则{
迭代器itr=临时迭代器();
字符串电流=itr.next();
移除温度(电流);
设置pSetTemp=所有子集(温度);
用于(集合x:pSetTemp){
pSet.添加(x);
Set copySubset=新的HashSet();
copySubset.addAll(x);
copySubset.add(当前);
pSet.add(复制子集);
}
}
返回pSet;
}
正如我所说,这段代码是有效的,我只是无法解决实验室的第二部分,它要求使用一个函数来查找特定大小k的子集。下面是一个JavaScript示例,可以给您一些提示
函数f(S,k){
如果(S.size==k)
返回[S]
如果(k==0)
返回[新设置]
让结果=[]
for(让e/S){
S.删除(e)
设较小的=f(新集合,k-1)
对于(让我们使用较小的){
s、 加(e)
结果:推送(s)
}
}
返回结果
}
var S=新集合([1,2,3,4,5])
log(JSON.stringify(
f(S,3).map(S=>Array.from(S)))
如果你能找到所有的子集,是什么阻止你只向结果中添加大小为k的子集?我的教授已经明确指出,我们不应该这样做,因为这样做效率不高。例如,如果我们有一个大小为100的集,那么在powerset中就有2^100个子集。如果我们只需要大小为2的子集,我们就必须遍历所有子集才能得到它们。你说“函数接受……这个k值”,但你发布的代码没有k。因此,您需要添加参数k——我们可以将其描述为“要返回的集合的大小”——并记住,当递归时,我们希望向下传递(k-1),并且递归在k==0时停止(无需返回)