查找子集时出现逻辑错误

时间:2012-04-21 16:19:09

标签: java generics subset

我正在尝试将代码概括为find all subsets of a given string(重复的元素将被视为不同的元素)为一个适用于任何列表的代码。

public class Subsets{
private static <T> void RecursiveSubsets(List<List<T>> list, ArrayList<T> soFar, List<T> rest)
{
if(rest.isEmpty())
{
  list.add(soFar);
}
else
{
  List<T> remaining;
  if(rest.size() == 1)
  {
    remaining = new ArrayList<T>();
  }
  else
  {
    remaining = rest.subList(1, rest.size() - 1);
  }
  //include the element
  ArrayList<T> includeFirst = new ArrayList<T>(soFar);
  includeFirst.add(rest.get(0));
  RecursiveSubsets(list, includeFirst, remaining);
  //exclude the element
  RecursiveSubsets(list, soFar, remaining);
 }
}

public static <T> List<List<T>> getAllSubsets(List<T> set)
{
List<List<T>> subsets = new ArrayList<List<T>>();
RecursiveSubsets(subsets,new ArrayList<T>(),set);
return subsets;
}

public static void main(String [] args)
{
List<Integer> ints = new ArrayList<Integer>(){
  {
    add(0);add(1);add(2);add(3);
  }
};

List<List<Integer>> allSubsets = getAllSubsets(ints);
System.out.println("Total Subsets returned : " + allSubsets.size());
for(int i=0; i<allSubsets.size(); ++i)
  {
  for(int j=0; j<allSubsets.get(i).size(); ++j)
  {
    System.out.print(allSubsets.get(i).get(j) + " ");
  }
  System.out.println();
  }
 }
}

经过几次尝试后,我能够将其编译,但这是我得到的输出。 即使我有更多的整数,它仍然会返回这个。我无法弄清楚我错过了什么,需要帮助找到它。

$ java Subsets
Total Subsets returned : 4
0 1
0
1

2 个答案:

答案 0 :(得分:1)

这个(伪代码)的逻辑通常是:

List<List<T>> subsets( List<T> list ){

    if( list is empty ) return a list containing the empty list;

    // else:

    subsetsWithout = subsets( list w/o 0th element );

    result.addAll(subsetsWithout);

    for( subset in subsetsWithout )
        result.add( subset + list[0] )

    return result;
}

看起来你正在做的事情是不同的,而你试图通过函数参数返回的事实让它更加混乱。

答案 1 :(得分:1)

你的程序实际上几乎是正确的,你只是让子列表逻辑有点不对。

List.sublist的javadoc说

  

返回指定fromIndex(包含)和toIndex(独占)之间此列表部分的视图。

这里的“独家”一词至关重要。

如果你只是改变

remaining = rest.subList(1, rest.size() - 1);

remaining = rest.subList(1, rest.size());

您的代码有效。