全排列

package com.paixu;

/**
 * @ClassName AllSequenceChar
 * @Description 字符串的全排列
 * @Author Administrator
 * @Date 2019/5/31 14:10
 * @Version 1.0
 **/
public class AllSequenceChar {

    /**
     * 字符串的全排列
     * @param s
     * @param from
     * @param to
     */
    public static void permutation(char[] s,int from,int to) {
        if(to <= 1)
            return;
        if(from == to) {
            System.out.println(s);
        } else {

            for(int i=from; i<=to; i++) {
                if(isNeedSwap(s,from,i)){
                    swap(s,i,from); //交换前缀,使其产生下一个前缀
                    permutation(s, from+1, to);
                    swap(s,from,i); //将前缀换回,继续做上一个前缀的排列
                }
            }
        }
    }

    /*
     * 由于全排列就是从第一个数字起,每个数分别与它后面的数字交换,我们先尝试加个这样的判断——如果一个数与后面的数字相同那么这两个数就不交换 了。
     * 例如abb,第一个数与后面两个数交换得bab,bba。然后abb中第二个数和第三个数相同,就不用交换了。但是对bab,第二个数和第三个数不 同,则需要交换,
     * 得到bba。由于这里的bba和开始第一个数与第三个数交换的结果相同了,因此这个方法不行。
     * 换种思维,对abb,第一个数a与第二个数b交换得到bab,然后考虑第一个数与第三个数交换,此时由于第三个数等于第二个数,
     * 所以第一个数就不再用与第三个数交换了。再考虑bab,它的第二个数与第三个数交换可以解决bba。此时全排列生成完毕!
     */

    /**
     * 判断是否需要进行交换
     * @param s
     * @param from
     * @param k
     * @return
     */
    private static boolean isNeedSwap(char[] s, int from, int k) {
        boolean flag = true;
        for (int i = from; i < k; i ++) {
            if (s[i] == s[k]) {
                flag = false;
                break;
            }
        }
        return flag;
    }

    /**
     * 交换数组中两个元素
     * @param s
     * @param i
     * @param j
     */
    public static void swap(char[] s,int i,int j) {
        char tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }

    public static void main(String[] args) {
        char[] s = {'a','b','b'};
        permutation(s, 0, 2);
    }
}

  

posted @ 2019-05-31 15:22  林木声  阅读(119)  评论(0编辑  收藏  举报