输出n的全排列

输出n的全排列,有两种方法:

1. 采用递归插入的方法,如果知道n-1的全排列,n的全排列为将数值n插入的n-1的全排列之间的空隙和两头共n个位置。

2. 采用递归标记填充的方法,查看标记数组,将未标记的数值依次填充当前位置,然后更新标记数组并递归下一位置。


Java代码:

public class Factorial {

 

    /**

     * @param args

     */

    public static int count = 0;

 

    public static void main(String[] args) {

        testinsertFact(7);

        testFlagFact(7);

    }

 

//    交换数组array中位置i和位置j的数值

    public static void swap(int[] array,int i, int j) {

        // ij相等的时候,使用异或交换同一个数将会使得该数值为0

        if (i != j) {

            array[i] = array[i] ^ array[j];

            array[j] = array[i] ^ array[j];

            array[i] = array[i] ^ array[j];

        }

    }

 

//    方法一,采用递归插入的方法

//    如果知道n-1的全排列,n的全排列为把数值n插入到n-1的全排列的第1位,第2...n位,

//    即插入n-1全排列的n-1个数的之间的空隙和两头,共有n种。

    public static void insertFact(int[] array,int n) {

//        n=0时,输出排列

        if (n <= 0) {

            count++;

            for (int i = 1; i < array.length; i++)

                System.out.print(array[i] +" ");

            System.out.println();

        }

//        求解n的全排列,将数值nn-1全排列的第1位到第n位交换

        for (int i = 1; i <= n; i++) {

//            交换

            swap(array, i, n);

//            递归求解

            insertFact(array, n - 1);

//            还原交换

            swap(array, i, n);

        }

    }

    public static void testinsertFact(int n){

        for (int i = 1; i < n; i++) {

            count = 0;

            int rightCount = 1;

            int[] array =new int[i + 1];

            for (int j = 1; j <= i; j++) {

               rightCount *= j;

                array[j] = j;

            }

            insertFact(array, i);

            System.out.println("Result:" + (count == rightCount));

            System.out.println("ComputeCount:\t" +count);

            System.out.println("RightCount:\t" + rightCount);

            System.out.println("*******************");

        }

    }

   

//    方法二,采用递归标记填充的方法

//    通过标记来填充数组,如果该数已经放入数组中了,则标记为true,否则标记为false

//    在当前位置填充数据时,查看标记数组,可以填充未标记的所有值。

    public static void flagFact(boolean[] flags,int[] array,int loc){

        if(array.length==loc){

//            当位置超出范围,输出排列

            count++;

            for (int i = 1; i < array.length; i++)

                System.out.print(array[i] +" ");

            System.out.println();

        }else{

//            查看标记数组,将未标记的所有值依次填入当前位置

            for(int i=1;i<flags.length;i++){

                if(!flags[i]){

//                    填充

                    array[loc]=i;

//                    重新标记

                    flags[i]=true;

//                    递归求解

                    flagFact(flags,array, loc+1);

//                    恢复标记

                    flags[i]=false;

                }

            }

        }

    }

    public static void testFlagFact(int n){

        for (int i = 1; i < n; i++) {

            count = 0;

            int rightCount = 1;

            int[] array =new int[i + 1];

            boolean[] flags=newboolean[i+1];

            for (int j = 1; j <= i; j++) {

                rightCount *= j;

                array[j] = j;

                flags[j]=false;

            }

            flagFact(flags,array, 1);

            System.out.println("Result:" + (count == rightCount));

            System.out.println("ComputeCount:\t" +count);

            System.out.println("RightCount:\t" + rightCount);

            System.out.println("*******************");

        }

    }

}


下载地址:

http://download.youkuaiyun.com/detail/ssuchange/6711055


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值