数组,字符串全排列算法分析(字典序生成法)

来源:互联网 发布:网络流行红歌 编辑:程序博客网 时间:2024/06/05 17:37

先看一个题:

题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。

输入描述: 输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

就是输入一个字符串,按字母顺序输出全排列后的字符串。下面说一个字典序方法。

先用一个比较简单的数字字符串举例子,原理相同。假设我们给定一个数字字符串87632491,我们找出下一个比他大的字典序列。

1.从最右边往左边扫描,找到第一个数字符合如下标准,该数字的右邻比他大。从上面的例子我们能够看到,该数字是4,下标是i=5(从0开始);
2.从上面找到的数组下标i开始从左向右扫描,找到i右边比4大的元素中最小的一个。很容易的就能够找到,是1,下标j=7;
3.交换i和j位置的元素。交换后是87632194。
4.逆序i+1到n位置的元素。逆序后是87632149
5.处理后的字符串就是我们要找的下一个字典序中的字符串。回到第一步继续迭代即可找到所有排列。

    public ArrayList<String> Permutation(String str) {         ArrayList<String> res = new ArrayList<String>();        if (str==null||str.length()==0) {            return res;        }        //将字符串转成字节数组,方便排序        char [] a = str.toCharArray();        //按字母表中的位置排序,如果忽略此步,会导致找到的全排列有所丢失。即给定字符串是bac,如果不重新排列成abc,那么abc-bac之间的字典序字符串会丢失        Arrays.sort(a);        while (true) {            res.add(String.valueOf(a));            int i = 0;            //从右向左,寻找第一个比右邻小的元素,找到停止,负责一致扫描完整个数组            for (i = a.length-2; i >=0&&a[i]>=a[i+1] ; i--);                        int j = i;            //如果j==-1,也就是上面的for循环没找到符合的元素,说明现在的数组从左向右是递减的,即最后一个字典序,返回整个集合            if (j == -1) {                return res;            }            //找到符合的元素j后,反向扫描,寻找比j元素大的中最小的一个。其实整个地方比较简单,我们在第一次for循环时,找到j,说明从n到j,即数组从右向左一直到j,是递增的,否则不会找到j。所以我们只需要从数组最右端先左扫描即可找到第一个比j大的,即使符合要求的。            for (i = a.length-1; i>0&&a[i]<=a[j]; i--);                     int k = i;            //找到j和k元素后,交换两个元素,            char b = a[j];            a[j] = a[k];            a[k] = b;            //上面的工作我们只是找到了j位置的元素,j+1到n位置的元素还是一个递增的,不符合字典序,下面是逆序的过程            for (int l = j+1; l < (a.length+j)/2+1; l++) {                char c = a[l];                a[l] = a[a.length-l+j];                a[a.length-l+j] = c;            }            //全部处理完,找到所需要的字典序,在找到的字典序数组基础上,再去找下一个字典序        }    }

更多的方法,待更新。

后续更新————————————————–
递归的方法

// 递归的方法    static public ArrayList<String> Permutation1(String str) {        ArrayList<String> res = new ArrayList<String>();        if (str == null || str.length() == 0) {            return res;        }        char a[] = str.toCharArray();        Arrays.sort(a);        //res.add(String.valueOf(a));        swap(a, 0, res);        // Collections.sort(res);        for (String s : res) {            System.out.println(s);        }        return res;    }    static void swap(char a[], int start, ArrayList<String> res) {        if (start == a.length-1) {            res.add(String.valueOf(a));        }else {            for (int j = start; j < a.length; j++) {                if (start==j||a[j] != a[start]) {                    char b = a[j];                    a[j] = a[start];                    a[start] = b;                    res.add(String.valueOf(a));                    swap(a, start + 1, res);                    b = a[j];                    a[j] = a[start];                    a[start] = b;                }            }        }    }

Good Good Study,Day Day Up。

0 0
原创粉丝点击