这是另一个关于排列的问题。我尽我所能尽我所能地制定我的问题。如果您有不明白的事情,请随时提问。
我有一个列表,其中包含一个列表,其中包含一个包含符号的列表。
List<List<List<Symbol>>> list = new ArrayList<List<List<Symbol>>>();
符号类只接受一个值并跟踪我正在创建的一些重要特征。结构中的所有符号彼此不同。
然而,由于......
,因此只能以各种方式切换位置存在一些困难第一个列表是整个事物的一种包装。它包含两个包含符号的列表的分组。这是因为当包含在分组中时,符号不应该彼此分开。
第二个列表的长度始终为2,每个列表都包含一个唯一符号列表。至于它为什么是两个,不要问我这个问题。对于这个程序来说,能够处理这个长度大于两个的列表会很不错。
第三个列表包含所有符号,每个包装器中有两个符号,如上所述。
我想要的是生成所有可能的排列并分析它们。也就是说,我希望符号切换到所有可能的组合,同时仍然包含在其各自的列表中。
这可能看起来像这样(用伪代码编写,描绘了上面提到的类似列表的结构)。
[[a, b, c], [d, e, f]],
[[g, h, i, j], [k, l, m, n]],
[[o, p], [q, r]],
[[s, t, u], [v, x, y]],
这可能是一个(可能是数千个)排列之一的例子。
[[c, a, b], [d, f, e]],
[[g, h, j, i], [k, l, m, n]],
[[o, p], [q, r]],
[[s, t, u], [v,y, x]],
我到目前为止所尝试的是将这些放入一个很好的旧传统排列方法,适用于单个数组(或列表,如果你愿意),并试图将其修改为使用多维数组。当然有一个很好的简单方法,最好使用递归。如果没有办法,那就完全可以了。
如果您对我刚写的内容有任何疑问,请随时发表评论。
亲切的问候,
答案 0 :(得分:1)
这是一个递归解决方案。 import java.util.*;
public class Perm {
static <T> List<List<T>> permutations(List<T> list) {
if(list.isEmpty()) return new LinkedList<>();
List<List<T>> result = new LinkedList<>();
for(int i = 0; i < list.size(); i++) {
T elem = list.get(i);
List<T> copy = new LinkedList<>(list);
copy.remove(i);
List<List<T>> permRest = permutations(copy);
if(permRest.isEmpty()) permRest.add(new LinkedList<>());
for(List<T> perm: permRest) {
List<T> permCopy = new LinkedList<>(perm);
permCopy.add(0, elem);
result.add(permCopy);
}
}
return result;
}
@SuppressWarnings("unchecked")
static List<List> permutationsLists(List list) {
if(list.size() == 0) {
return new LinkedList<>();
} if(!(list.get(0) instanceof List)) {
return permutations(list);
} else {
List<List> permutationsFirst = permutationsLists((List)list.get(0));
List<List> permutationsRest = (List<List>)permutationsLists(list.subList(1, list.size()));
if(permutationsRest.size() == 0) permutationsRest.add(new LinkedList());
List<List> result = new LinkedList<>();
for(List pf: permutationsFirst) {
for(List pr: permutationsRest) {
List copy = new LinkedList(pr);
copy.add(0, pf);
result.add(copy);
}
}
return result;
}
}
public static void main(String[] args) {
/*
List<List<List<String>>> list = Arrays.asList(
Arrays.asList(Arrays.asList("a", "b", "c"), Arrays.asList("d", "e", "f")),
Arrays.asList(Arrays.asList("g", "h", "i", "j"), Arrays.asList("k", "l", "m", "n")),
Arrays.asList(Arrays.asList("o", "p"), Arrays.asList("q", "r")),
Arrays.asList(Arrays.asList("s", "t", "u"), Arrays.asList("v", "w", "x"))
);
*/
List<List<Integer>> list = Arrays.asList(Arrays.asList(1,2,3), Arrays.asList(4,5));
System.out.println(permutationsLists(list));
}
}
可以获取具有任意数量维度的列表。顺便说一句。你给出的例子有近300万个排列。我的程序需要几秒钟来计算所有这些。
iterator()
编辑:
这是一个使用流的解决方案。它非常高效,可以产生大量的排列而不会占用太多的内存。顺便说一下,您可以使用import java.util.*;
import java.util.stream.Stream;
import java.util.stream.IntStream;
public class Perm {
static <T> Stream<List<T>> permutations(List<T> list) {
if(list.isEmpty()) return Stream.empty();
return IntStream.range(0, list.size()).boxed().flatMap(i -> {
T elem = list.get(i);
List<T> copy = new LinkedList<>(list);
copy.remove((int)i);
Stream<List<T>> permRest = copy.isEmpty()?Stream.of(new LinkedList<>()):permutations(copy);
return permRest.map(perm -> {
List<T> permCopy = new LinkedList<>(perm);
permCopy.add(0, elem);
return permCopy;
});
});
}
@SuppressWarnings("unchecked")
static <T> Stream<List<T>> permutationsLists(List<T> list) {
if(list.size() == 0) {
return Stream.empty();
} if(!(list.get(0) instanceof List)) {
return permutations(list);
} else {
List rawList = list;
Stream<List> permutationsFirst = permutationsLists((List)list.get(0));
return permutationsFirst.flatMap(pf -> {
Stream<List> permutationsRest = list.size() < 2?Stream.of(new LinkedList()):permutationsLists(rawList.subList(1, list.size()));
return permutationsRest.map(pr -> {
List<T> copy = new LinkedList<>(pr);
copy.add(0, (T)pf);
return copy;
});
});
}
}
public static void main(String[] args) throws Exception {
List<List<List<String>>> list = Arrays.asList(
Arrays.asList(Arrays.asList("a", "b", "c"), Arrays.asList("d", "e", "f")),
Arrays.asList(Arrays.asList("g", "h", "i", "j"), Arrays.asList("k", "l", "m", "n")),
Arrays.asList(Arrays.asList("o", "p"), Arrays.asList("q", "r")),
Arrays.asList(Arrays.asList("s", "t", "u"), Arrays.asList("v", "w", "x"))
);
Stream<List<List<List<String>>>> result = permutationsLists(list);
result.forEach(p -> System.out.println(p));
}
}
方法将流转换为迭代器。
{{1}}