输出4个整数(不重复)的所有排列组合

给定数组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]······)
	}
}

这种算法的循环次数较少,应该是复杂度较优的

    原文作者:lsjweiyi
    原文地址: https://blog.csdn.net/lsjweiyi/article/details/68495556
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞