public class Algorithms {
public Algorithms() {
}
private static <T> void subCombination(List<List<T>> out,List<T> in,
List<T> temp,int index,int nloop,int nth){
if (index == nth){ //get the result
out.add(temp);
System.out.println(temp);
}
else{
for (int loop = nloop;loop < in.size();++loop){
temp.set(index,in.get(loop));
subCombination(out,in,temp,index+1,loop+1,nth); //backtracking
}
}
}
public static <T> void combination(List<List<T>> out,List<T> in,int nth){
if (nth >= in.size())
return;
List<T> temp = new ArrayList<T>(nth);
for (int i = 0;i < nth;++i)
temp.add(null);
subCombination(out,in,temp,0,0,nth);
}
public static void main (String[] args) {
List<String> ls = new ArrayList<String>();
ls.addAll(Arrays.asList("a","b","c","d","e","f","g","h"));
List<List<String>> comb = new ArrayList<List<String>>();
combination(comb,ls,7);
System.out.println(comb);
}
}
输出:
[a, b, c, d, e, f, g]
[a, b, c, d, e, f, h]
[a, b, c, d, e, g, h]
[a, b, c, d, f, g, h]
[a, b, c, e, f, g, h]
[a, b, d, e, f, g, h]
[a, c, d, e, f, g, h]
[b, c, d, e, f, g, h]
[[h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h]]
输出的两部分,其中前面正确的结果是因为在算法中检测输出结果,而后面错误的输出是实际提取出来的组合结果。
问题1:
我知道错误的原因是因为“浅拷贝”的问题,在out.add(temp);一句中,out中的结果和temp做了个映射,而temp是不断改变的。
我想知道在此处用“深拷贝”该如何实现?进一步,java中对象“深拷贝”的实现。
注:不仅是那里,因为浅拷贝的原因,使得方法返回的结果和输入建立映射,改变其一,会引起另一不期望的改变。
问题2:
总所周知,java的泛型不允许创建泛型数组,即T[] temp = new T[nth];所以我把temp实现为List<T>,并且因为要使用set来改变位置元素,所以很别扭的采用一个for循环再赋值null的方法。其实很不想这样做,有没有什么更好的方法实现temp这个变量?
………………………………………………………………………………………………………………………………………………
这是个使用递归回溯的计算组合的算法,闲来没事用java实现下,准备放进我的库里。这个算法用c++我是实现过的,也是用的泛型。
大家帮下忙,我没接触过java中的数据结构和算法,代码里的不合理的地方希望指导一下。