2 回答
TA贡献1808条经验 获得超4个赞
有一种更简单、更快的解决方案,不需要递归。
可以提前计算输出组合的数量:在您的情况下乘以属性,2*2*2
但对于每个组合都是如此。
此外,我们可以根据组合索引计算每个组合中将放置哪个值。如果我们假设组合索引从0至7:
用于A
:
-组合0-3将包含a1
-组合4-7将包含a2
对B
-组合0,1,4,5将包含b1
-组合2,3,6,7-将包含b2
for C
- 组合 0,2,4,6 将包含c1
- 组合 1,3,5,7 将包含c2
因此,值放置的公式基于组合索引、属性的顺序(A
第一个等)以及属性中值的顺序。
该算法的复杂度为 o(n*m),其中 n 是属性数和 m 值数。
TA贡献1725条经验 获得超7个赞
从Java 中任意集合的笛卡尔积修改而来
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class CartesianProduct {
public static Set<Set<Object> > cartesianProduct(Set<?>... sets) {
if (sets.length < 2)
throw new IllegalArgumentException(
"Can't have a product of fewer than two sets (got " +
sets.length + ")");
return _cartesianProduct(0, sets);
}
private static Set<Set<Object> > _cartesianProduct(int index, Set<?>... sets) {
Set<Set<Object> > ret = new TreeSet<Set<Object> >(new Comparator<Set<Object> >() {
@Override
public int compare(Set<Object> o1, Set<Object> o2) {
return o1.toString().compareTo(o2.toString());
}
});
if (index == sets.length) {
ret.add(new TreeSet<Object>());
} else {
for (Object obj : sets[index]) {
for (Set<Object> set : _cartesianProduct(index+1, sets)) {
set.add(obj);
ret.add(set);
}
}
}
return ret;
}
public static void main(String[] args) {
Map<String, Set<String> > dataMap = new HashMap<String, Set<String> >();
dataMap.put("A", new TreeSet<String>(Arrays.asList("a1", "a2")));
dataMap.put("B", new TreeSet<String>(Arrays.asList("b1", "b2")));
dataMap.put("C", new TreeSet<String>(Arrays.asList("c1", "c2")));
System.out.println(cartesianProduct(dataMap.values().toArray(new Set<?>[0])));
}
}
添加回答
举报