輸出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]······)
}
}
這種演算法的迴圈次數較少,應該是複雜度較優的