给定数组int[] a={1,2,3,4},输出这四个数的所有排列组合。
答案为:
1 2 3 4,1 2 4 3,1 3 2 4,1 3 4 2,1 4 2 3,1 4 3 2
2 1 3 4,2 1 4 3,2 3 1 4,2 3 4 1,2 4 1 3,2 4 3 1
3 1 2 4,3 1 4 2,3 2 1 4,3 2 4 1,3 4 1 2,3 4 2 1
4 1 2 3,4 1 3 2,4 2 1 3,4 2 3 1,4 3 1 2,4 3 2 1
共24种(顺序可变)。
不难,看代码:
public class CombinationOf4Int {
public static void main(String[] args) {
int value=0;//每输出一次加1,到6时换行,后面的逗号就不需要输出了
int[] array={1,2,3,4};
//共四个循环
for(int i=0;i<4;i++){
System.out.println();
for(int j=0;j<4;j++){
if(j==i)//除去j==i的情况,下同
continue;
for(int k=0;k<4;k++){
if(k==j||k==i)
continue;
for(int h=0;h<4;h++){
if(h==k||h==j||h==i)
continue;
System.out.print(array[i]+" "+array[j]+" "+array[k]+" "+array[h]);//输出
value++;
if(value%6==0)//一行输出6组,行末不需要输出逗号,所以跳过
continue;
System.out.print(", ");
}
}
}
}
}
}
还有另外一种方法,输出结果为:
0 1 2 3 , 1 2 3 0 , 2 3 0 1 , 3 0 1 2
0 2 3 1 , 1 3 0 2 , 2 0 1 3 , 3 1 2 0
0 3 1 2 , 1 0 2 3 , 2 1 3 0 , 3 2 0 1
0 1 3 2 , 1 2 0 3 , 2 3 1 0 , 3 0 2 1
0 2 1 3 , 1 3 2 0 , 2 0 3 1 , 3 1 0 2
0 3 2 1 , 1 0 3 2 , 2 1 0 3 , 3 2 1 0
public class CombinationOf4Int2 {
public static void main(String[] args) {
int[] array={0,1,2,3};
//共三个循环,且循环总次数为24,比前面的方法少
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
for(int k=0;k<4;k++){
System.out.print(array[k%4]+" "+array[(k+j%3+1)%4]+" "+array[(k+(j+i%2+1)%3+1)%4]+" "+array[(k+(j+(i+1)%2+1)%3+1)%4]+" ");
if(k==3){
System.out.println();
continue;
}
System.out.print(", ");
}
}
}
}
}
就解释那一行输出,看例子:
一、
int[] a={0,1}有两种组合①0,1②1,0,用式子表示
for(int i=0;i<2;i++){
system.out.println(a[i%2]+" "+a[(i+1)%2])
}
当i=0时,system.out.println(a[0%2]+" “+a[(0+1)%2])=system.out.println(a[0]+” “+a[1])=0 1
当i=1时,system.out.println(a[1%2]+” “+a[(1+1)%2])=system.out.println(a[1]+” "+a[0])=1 0
二、
int[] a={0,1,2}有组合①0,1,2②1,0,2等6种组合,用式子表示
for(int i=0;i<3;i++){
system.out.println(a[i%3]+" "+a[(i+1)%3]+" "+a[(i+2)%3])
}
当i=0时,system.out.println(a[0%3]+" “+a[(0+1)%3]+” “+a[(0+2)%3])=system.out.println(a[0]+” “+a[1]+” “+a[2])=0 1 2
当i=1时,system.out.println(a[1%3]+” “+a[(1+1)%3]+” “+a[(1+2)%3])=system.out.println(a[1]+” “+a[2]+” “+a[0])=1 2 0
当i=2时,system.out.println(a[2%3]+” “+a[(2+1)%3]+” “+a[(2+2)%3])=system.out.println(a[2]+” “+a[0]+” "+a[1])=2 0 1
这样子只能输出3种。
实际要这么写:
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
system.out.println(a[j%3]+" "+a[(j+i%2+1)%3]+" "+a[(j+(i+1)%2+1)%3])
}
}
输出为:0 1 2 , 1 2 0, 2 0 1 , 0 2 1 ,1 0 2 , 2 1 0
这里的思想是加1取余:
任何整数对3取余只能得到三个结果:0,1,2,和上面的数字完全吻合,那么:对0 1 2,每个数加1,并且对3取余得:1 2 0,再加1取余:2 0 1,也就是第二个例子:
for(int i=0;i<3;i++){
system.out.println(a[i%3]+" "+a[(i+1)%3]+" "+a[(i+2)%3])
}
得出的结果是一样的。那么要得到另外三种排列呢?是不是应该先把0 1 2变成0 2 1,然后得:0 2 1,1 0 2,2 1 0。那么式子应该变成:
for(int i=0;i<3;i++){
system.out.println(a[i%3]+" "+a[(i+2)%3]+" "+a[(i+1)%3])
}
放到一起看:
for(int i=0;i<2;i++){
system.out.println(a[i%2]+" "+a[(i+1)%2])
}
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
system.out.println(a[j%3]+" "+a[(j+i%2+1)%3]+" "+a[(j+(i+1)%2+1)%3])
}
}
for(int i=0;i<2;i++){
for(int j=0;j<3;j++){
for(int k=0;k<4;k++){
System.out.print(a[k%4]+" "+a[(k+j%3+1)%4]+" "+a[(k+(j+i%2+1)%3+1)%4]+" "+a[(k+(j+(i+1)%2+1)%3+1)%4]+" ");
规律这样看应该很明显了吧,下一种情况是上面一种情况的基础上加了一些东西,始终符合:
int n;//n>2
for(int i=0;i<n-1;i++){
for(int j=0;j<n;j++){
system.out.println(a[j%n]+" "+a[(j+i%(n-1)+1)%n]+" "+a[(j+(i+1)%(n-1)+1)%n]······)
}
}
这种算法的循环次数较少,应该是复杂度较优的