我读了一种递归生成字符串排列的算法。
invoke the function with j = 1 if (j == length of string) print the string and return else for (i = j to length of string) interchange jth character with ith character call function on j + 1
我使用java实现了这个:
class PERMUTATION {
private int count = 1;
private char[] arr = {'A', 'B', 'C'};
public void perm(int k) {
if (k == 3) {
System.out.print(count+++".");
for (int i = 0; i < 3; ++i)
System.out.print(arr[i]+" ");
System.out.println();
return;
}
for (int i = k; i <= 3; ++i) {
/*interchanging ith character with kth character*/
char c = arr[i - 1];
arr[i - 1] = arr[k - 1];
arr[k - 1] = c;
perm(k + 1);
}
}
public static void main(String []args) {
System.out.println("the permutations are");
PERMUTATION obh=new PERMUTATION();
obh.perm(1);
}
}
但我的程序正在产生重复的排列。为什么呢?
答案 0 :(得分:4)
如果“源”数组保持不变,则此算法有效,因此将正确处理每个索引。
让我们看一下代码的输出:
1.A B C
2.A C B
3.C A B
4.C B A
5.A B C
6.A C B
正如你所看到的,在迭代中没有。 3,它应该将 B 转移到第一个索引,而是移动 C ,因为你已经将 B 移动到另一个位置。 由于这个事实, B 没有机会获得第一个索引,只会在2到3之间“反弹”。
您的主要问题是,您正在更改“源”阵列。如果你避免这种情况,那么你的算法可以正常工作:
class PERMUTATION {
private int count = 1;
public void perm(char[] arr, int k) {
if (k == 3) {
System.out.print(count++ + ".");
for (int i = 0; i < 3; ++i)
System.out.print(arr[i] + " ");
System.out.println();
return;
}
char[] arr2 = arr.clone(); // clone the passed array, so we don't mess it up
for (int i = k; i <= 3; ++i) {
/* interchanging ith character with kth character */
char c = arr2[k - 1];
arr2[k - 1] = arr2[i - 1];
arr2[i - 1] = c;
perm(arr2, k + 1);
}
}
public static void main(String[] args) {
System.out.println("the permutations are");
PERMUTATION obh = new PERMUTATION();
obh.perm(new char[] {'A', 'B', 'C'}, 1); // pass the original array
}
}
输出将是:
1.A B C
2.A C B
3.B A C
4.B C A
5.C A B
6.C B A
顺便说一下:请注意Java Naming Conventions,所以不要打电话给你的班级PERMUTATION
,而是使用Permutation
。