我在编写返回ArrayList的所有排列的方法代码时遇到了一些问题。
我找到了算法:
public class MainClass {
public static void main(String args[]) {
permuteString("", "String");
}
public static void permuteString(String beginningString, String endingString) {
if (endingString.length() <= 1)
System.out.println(beginningString + endingString);
else
for (int i = 0; i < endingString.length(); i++) {
String newString = endingString.substring(0, i) + endingString.substring(i + 1);
permuteString(beginningString + endingString.charAt(i), newString);
}
}
}
哪个适用于字符串,但是当我尝试为ArrayLists重写时 - 我发现了一些麻烦。
这是我写的代码:
private static ArrayList<ArrayList<Point>> listaPermutacji = new ArrayList<ArrayList<Point>>();
public static void perm(ArrayList<Point> soFar, ArrayList<Point> rest) {
if (rest.size() <= 1) {
ArrayList<Point> temp = new ArrayList<Point>();
temp = soFar;
for (int i = 0; i < rest.size(); i++) {
temp.add(rest.get(i));
}
listaPermutacji.add(temp);
} else {
for (int k = 0; k < rest.size(); k++) {
ArrayList<Point> remaining = new ArrayList<Point>();
List<Point> sublist = rest.subList(0, k);
for (int a = 0; a < sublist.size(); a++) {
remaining.add(sublist.get(a));
}
sublist.clear();
if (rest.size() >= k + 1) {
sublist = rest.subList(k + 1, rest.size());
for (int a = 0; a < sublist.size(); a++) {
remaining.add(sublist.get(a));
}
}
ArrayList<Point> beginning = new ArrayList<Point>();
beginning = soFar;
System.out.println("Beginning size= " + beginning.size());
System.out.println("Rest size= " + rest.size());
System.out.println("k= " + k);
if(k<rest.size()){
beginning.add(rest.get(k));
}
perm(beginning, remaining);
}
}
}
这是返回,例如对于3点阵列:
x= 4.0 y= 3.0 | x= 1.0 y= 0.0 | x= 0.0 y= 1.0 | x= 1.0 y= 0.0 | x= 0.0 y= 1.0 | x= 4.0 y= 3.0 |
x= 4.0 y= 3.0 | x= 1.0 y= 0.0 | x= 0.0 y= 1.0 | x= 1.0 y= 0.0 | x= 0.0 y= 1.0 | x= 4.0 y= 3.0 |
x= 4.0 y= 3.0 | x= 1.0 y= 0.0 | x= 0.0 y= 1.0 | x= 1.0 y= 0.0 | x= 0.0 y= 1.0 | x= 4.0 y= 3.0 |
我真的无法理解......我试图解决这个问题大约4个小时,我还有其他问题......
顺便说一句,我需要这个发电机来制定解决旅行商问题的强力方法......
提前致谢。
答案 0 :(得分:1)
也许你的错误在那里:
ArrayList<Point> temp = new ArrayList<Point>();
temp = soFar;
如果您希望temp
成为副本(新列表),则应将这两行替换为ArrayList<Point> temp = new ArrayList<Point>(soFar);
答案 1 :(得分:0)
好吧,我发现,使用Guava lib(如fge所说)可能是生成这些排列的最简单方法。所以,我尝试了这个解决方案......它的确有效!所以,谢谢大家的帮助。
答案 2 :(得分:0)
您要找的是Backtracking。这种解决问题的技术很大程度上基于递归。基本上,你设置你的第一个点,然后只考虑其他点作为子问题,并且当找到第一个点的每个排列时,它会递增,依此类推。
您的解决方案将如下所示。为简单起见,我使用了一个整数数组,但你应该能够轻松地将整数更改为点。将这些整数视为Arraylist中各点的索引。
public class PermutationDemo {
public static void main(String[] args) {
int[] array = new int[4];
for (int i=0; i<array.length; i++) {
reset(array, i);
}
solve(array, 0);
}
private static void solve(int[] array, int i) {
if (i == array.length) {
print(array);
return;
}
for (int k=0; k<4; k++) {
solve(array, i+1);
makeMove(array, i);
}
reset(array, i);
}
private static void makeMove(int[] array, int i) {
array[i] += 1;
}
private static void reset(int[] array, int i) {
array[i] = 1;
}
private static void print(int[] array) {
for (int i=0; i<array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println("");
}
}
结果是:
PS [10:21] Desktop > java PermutationDemo
1 1 1
1 1 2
1 1 3
1 1 4
1 2 1
1 2 2
1 2 3
1 2 4
1 3 1
1 3 2
1 3 3
1 3 4
1 4 1
1 4 2
1 4 3
1 4 4
2 1 1
2 1 2
2 1 3
2 1 4
2 2 1
2 2 2
2 2 3
2 2 4
2 3 1
2 3 2
2 3 3
2 3 4
2 4 1
2 4 2
2 4 3
2 4 4
3 1 1
3 1 2
3 1 3
3 1 4
3 2 1
3 2 2
3 2 3
3 2 4
3 3 1
3 3 2
3 3 3
3 3 4
3 4 1
3 4 2
3 4 3
3 4 4
4 1 1
4 1 2
4 1 3
4 1 4
4 2 1
4 2 2
4 2 3
4 2 4
4 3 1
4 3 2
4 3 3
4 3 4
4 4 1
4 4 2
4 4 3
4 4 4