Java 递归获取powerset
我想先说这是学校作业,所以虽然我需要帮助,但最好给我指出正确的方向,而不是给我代码 因此,任务是能够打印出任何给定集合的PowerSet(给定集合的所有子集的集合)。我对Java有一定的经验,但递归是我的弱点之一,所以我很难将其可视化 我的方法返回所有包含“d”和空集的子集 以下是我目前掌握的情况:Java 递归获取powerset,java,recursion,set,powerset,Java,Recursion,Set,Powerset,我想先说这是学校作业,所以虽然我需要帮助,但最好给我指出正确的方向,而不是给我代码 因此,任务是能够打印出任何给定集合的PowerSet(给定集合的所有子集的集合)。我对Java有一定的经验,但递归是我的弱点之一,所以我很难将其可视化 我的方法返回所有包含“d”和空集的子集 以下是我目前掌握的情况: public static TreeSet<TreeSet<Character>> powerSet(TreeSet<Character> setIn) {
public static TreeSet<TreeSet<Character>> powerSet(TreeSet<Character> setIn)
{
Comparator<TreeSet<Character>> comp = new Comparator<TreeSet<Character>>()
{
@Override
public int compare(TreeSet<Character> a, TreeSet<Character> b)
{
return a.size() - b.size();
}
};
TreeSet<TreeSet<Character>> temp = new TreeSet<TreeSet<Character>>(comp);
if (setIn.isEmpty())
{
temp.add(new TreeSet<Character>());
return temp;
}
Character first = setIn.first();
msg(first);
setIn.remove(first);
TreeSet<TreeSet<Character>> setA = powerSet(setIn);
temp.addAll(setA);
for (TreeSet<Character> prox : setA)
{
TreeSet<Character> setB = new TreeSet<Character>(prox);
setB.add(first);
temp.add(setB);
}
return temp;
}
这个方法给了我一套
[[], [d], [c, d], [b, c, d], [a, b, c, d]]
但是我们知道动力装置应该是
[[], [a], [b], [c], [d], [a, b], [a, c], [a, d], [b, c], [b, d], [c, d],
[a, b, c], [a, b, d], [a, c, d], [b, c, d], [a, b, c, d]]
任何朝着正确方向提供的帮助都将不胜感激
编辑:我的问题真是个愚蠢的问题。我忘了正确设置比较器,它排除了结果。我修复了比较器,使其能够正确排序,而不会丢弃集合
这是:
public int compare(TreeSet<Character> a, TreeSet<Character> b)
{
if(a.equals(b))
return 0;
if(a.size() > b.size())
return 1;
return -1;
}
公共整数比较(树集a、树集b)
{
如果(a等于(b))
返回0;
如果(a.size()>b.size())
返回1;
返回-1;
}
到目前为止看起来不错
您正在构建包含第一个元素的每个可能子集
这可以非常简单地扩展为对初始集的每个元素执行相同的操作。只需要做你已经在做的事情,但是对于初始集合的不同元素
这将使您更接近电源集。广泛编辑:
解决方案比我最初想象的要简单得多。除了以下几点之外,您做得非常好:在从集合中删除第一个元素之前,将集合添加到temp
集合中
大概是这样的:
temp.add(setIn);
Character first = setIn.first();
msg(first);
setIn.remove(first);
但是如果你看一下这里给出的算法,你只需要删除任何一个特定的元素(这里,那里第一个),然后递归地找到剩余元素的幂集。我一直在尝试实现这一点,但无论出于什么原因,我都很难想象如何做到这一点。我尝试使用循环(可能是个糟糕的主意)都以堆栈溢出而告终
Character first=setIn.first();树集setA=null;对于(int x=0;x
它最终导致堆栈溢出,因为停止条件(即集合为空)从未满足;您正在使用作为参数传递给当前方法执行的相同集合(setIn
)递归调用该方法。只有在递归调用之后,才能从该数组中删除元素。不幸的是,这一行永远无法到达,因为递归调用最终会导致堆栈溢出。@slider其中的算法说,要做到这一点,必须将删除的元素与通过从初始集合中删除该元素而获得的集合的所有子集相结合。这是正确的,这是一个比我提议的更好的方法。(我的变体会导致重复子集)@Caboose我误解了你的问题。我用改进的(阅读完全不同的)解决方案编辑了我的答案。
temp.add(setIn);
Character first = setIn.first();
msg(first);
setIn.remove(first);