我编写了一个程序来查找给定项目列表的所有可能的排列。这恰恰意味着我的程序打印了r = 0到n
的所有可能的P(n,r)值以下是代码:
package com.algorithm;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Permutations<T> {
public static void main(String args[]) {
Permutations<Integer> obj = new Permutations<Integer>();
Collection<Integer> input = new ArrayList<Integer>();
input.add(1);
input.add(2);
input.add(3);
Collection<List<Integer>> output = obj.permute(input);
int k = 0;
Set<List<Integer>> pnr = null;
for (int i = 0; i <= input.size(); i++) {
pnr = new HashSet<List<Integer>>();
for(List<Integer> integers : output){
pnr.add(integers.subList(i, integers.size()));
}
k = input.size()- i;
System.out.println("P("+input.size()+","+k+") :"+
"Count ("+pnr.size()+") :- "+pnr);
}
}
public Collection<List<T>> permute(Collection<T> input) {
Collection<List<T>> output = new ArrayList<List<T>>();
if (input.isEmpty()) {
output.add(new ArrayList<T>());
return output;
}
List<T> list = new ArrayList<T>(input);
T head = list.get(0);
List<T> rest = list.subList(1, list.size());
for (List<T> permutations : permute(rest)) {
List<List<T>> subLists = new ArrayList<List<T>>();
for (int i = 0; i <= permutations.size(); i++) {
List<T> subList = new ArrayList<T>();
subList.addAll(permutations);
subList.add(i, head);
subLists.add(subList);
}
output.addAll(subLists);
}
return output;
}
}
package com.algorithm;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Permutations<T> {
public static void main(String args[]) {
Permutations<Integer> obj = new Permutations<Integer>();
Collection<Integer> input = new ArrayList<Integer>();
input.add(1);
input.add(2);
input.add(3);
Collection<List<Integer>> output = obj.permute(input);
int k = 0;
Set<List<Integer>> pnr = null;
for (int i = 0; i <= input.size(); i++) {
pnr = new HashSet<List<Integer>>();
for(List<Integer> integers : output){
pnr.add(integers.subList(i, integers.size()));
}
k = input.size()- i;
System.out.println("P("+input.size()+","+k+") :"+
"Count ("+pnr.size()+") :- "+pnr);
}
}
public Collection<List<T>> permute(Collection<T> input) {
Collection<List<T>> output = new ArrayList<List<T>>();
if (input.isEmpty()) {
output.add(new ArrayList<T>());
return output;
}
List<T> list = new ArrayList<T>(input);
T head = list.get(0);
List<T> rest = list.subList(1, list.size());
for (List<T> permutations : permute(rest)) {
List<List<T>> subLists = new ArrayList<List<T>>();
for (int i = 0; i <= permutations.size(); i++) {
List<T> subList = new ArrayList<T>();
subList.addAll(permutations);
subList.add(i, head);
subLists.add(subList);
}
output.addAll(subLists);
}
return output;
}
}
输出
我的问题是,随着我增加输入列表中的数字。运行时间增加,输入列表中的11个数字后,程序几乎死亡。需要大约2 GB内存才能运行。
我在拥有8GB RAM和i5处理器的机器上运行它,因此速度和空间不是问题。
如果有人能帮助我编写更有效的代码,我将不胜感激。
答案 0 :(得分:14)
如果你没有存储它 - 如果你只是迭代它 - 那么考虑使用Heap的算法(http://www.cut-the-knot.org/do_you_know/AllPerm.shtml上的#3) - 或者,为了让你的生活更轻松,使用番石榴Collections2.permutations
,它实际上并没有构建整个排列列表 - 它在运行中遍历它们。 (披露:我向Guava捐款。)
答案 1 :(得分:8)
如果您想要15个或更多元素的所有排列,请将它们写入磁盘或数据库或其他内容,因为它们不适合内存。 编辑:Steinhaus–Johnson–Trotter algorithm。 这可能就是你要找的东西。
答案 2 :(得分:7)
Google(Guava)的Java库有一个实用方法:Collections2#permutations(Collection)
答案 3 :(得分:1)
您确实意识到您正在生成非常大的列表,并且运行时间将随着列表长度的增加而增加。你确定了给你麻烦的清单应该多长时间了吗?
可能对某些人有帮助的一件事就是在找到它们时打印每个排列,而不是将它们全部收集到列表中然后打印它们。当然,如果关键是要实际存储整个列表,而不仅仅是打印它们,那将无济于事。