输出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;i1;i++){
    for(int j=0;jsystem.out.println(a[j%n]+" "+a[(j+i%(n-1)+1)%n]+" "+a[(j+(i+1)%(n-1)+1)%n]······)
    }
}

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

你可能感兴趣的:(java学习,算法分析)