尝试重现Heap算法,用于生成整数数组的所有可能排列,但我不能解决其他整数而不是三个整数。 来自维基百科的Heap算法:
procedure generate(N : integer, data : array of any):
if N = 1 then
output(data)
else
for c := 1; c <= N; c += 1 do
generate(N - 1, data)
swap(data[if N is odd then 1 else c], data[N])
我的代码:
public static void perm(int[] list, int n){
if(n==1){
System.out.println(Arrays.toString(list));
} else {
for(int c=1;c<=n;c++){ /for(int c=0;c<n;c++)
perm(list,n-1);
if(n%2==0){
int temp1=list[c]; //This is line 17
list[c]=list[list.length-1];
list[list.length-1]=temp1;
}else{
int temp2=list[0];
list[0]=list[list.length-1];
list[list.length-1]=temp2;
}
}
}
}
我做错了什么,误解了什么?为什么它只能用[1,2,3](n = 3)作为输入,n = 2和n = 4?
运行:
perm(A,3);
[1, 2, 3]
[1, 3, 2]
[2, 3, 1]
[2, 1, 3]
[3, 1, 2]
[3, 2, 1]
perm(A,4)
[1, 2, 3, 4]
[1, 4, 3, 2]
.
.
.
[2, 4, 1, 3]
[2, 3, 1, 4]
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
at Permutation.perm(Permutation.java:17)
at Permutation.main(Permutation.java:43)
感谢您的回复,但这不是问题。我在问这个问题之前尝试改变它,但是如果我明确地理解了Wiki页面,那么从1开始就认为是算法的一部分(即使没有提到特定的语言/ for-loop-scheme)。下面是n = 4的输出,其中包含几个重复项。 链接到维基页面:http://en.wikipedia.org/wiki/Heap%27s_algorithm
[1, 2, 3, 4]
[4, 2, 3, 1]
[2, 1, 3, 4]
[4, 1, 3, 2]
[1, 2, 3, 4]
[4, 2, 3, 1]
[4, 1, 3, 2]
[2, 1, 3, 4]
[1, 4, 3, 2]
[2, 4, 3, 1]
[4, 1, 3, 2]
[2, 1, 3, 4]
[1, 2, 3, 4]
[4, 2, 3, 1]
[2, 1, 3, 4]
[4, 1, 3, 2]
[1, 2, 3, 4]
[4, 2, 3, 1]
[2, 1, 4, 3]
[3, 1, 4, 2]
[1, 2, 4, 3]
[3, 2, 4, 1]
[2, 1, 4, 3]
[3, 1, 4, 2]
答案 0 :(得分:2)
试试这个:
//Heap's Algorithm
public static void perm(int[] list, int n)
{
if(n == 1)
{
System.out.println(Arrays.toString(list));
}
else
{
for(int i=0; i<n; i++)
{
perm(list,n-1);
int j = ( n % 2 == 0 ) ? i : 0;
int t = list[n-1];
list[n-1] = list[j];
list[j] = t;
}
}
}
public static void main(String[] args) {
int[] list = new int[]{1,2,3};
perm(list, list.length);
}
您使用的是输入列表的长度,而不是&#34; n&#34;为你的交换
答案 1 :(得分:1)
在大多数现代编程语言中,数组都是0索引的,因此for(int c=1;c<=n;c++){
不是迭代元素的正确循环。伪代码假定1索引数组。
答案 2 :(得分:1)
更改此内容:
public static void perm(int[] list, int n){
if(n==1){
System.out.println(Arrays.toString(list));
} else {
for(int c=1;c<=n;c++){
perm(list,n-1);
if(n%2==0){
int temp1=list[c]; //This is line 17
list[c]=list[list.length-1];
list[list.length-1]=temp1;
}else{
int temp2=list[0];
list[0]=list[list.length-1];
list[list.length-1]=temp2;
}
}
}
}
对此:
public static void perm(int[] list, int n){
if(n==1){
System.out.println(Arrays.toString(list));
} else {
for(int c=0;c<n;c++){
perm(list,n-1);
if(n%2==0){
int temp1=list[c]; //This is line 17
list[c]=list[list.length-1];
list[list.length-1]=temp1;
}else{
int temp2=list[0];
list[0]=list[list.length-1];
list[list.length-1]=temp2;
}
}
}
}
答案 3 :(得分:0)
您确定c
在列表长度之上是否超出限定范围?
答案 4 :(得分:0)
4的数组包含索引0,1,2和3.Java(以及许多其他语言)从0开始计数。在第4行,您有以下循环:
for(int c=1;c<=n;c++){
从1(存在)开始,然后是2(存在),然后是3(存在),然后是4(数组超出范围)。
要修复,请更改循环:
for(int c = 0; c < n; c++){