数组,字符串全排列算法分析(字典序生成法)
来源:互联网 发布:网络流行红歌 编辑:程序博客网 时间: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
- 数组,字符串全排列算法分析(字典序生成法)
- 字典序法生成全排列算法
- 字典序全排列生成算法
- 全排列生成算法之字典序
- 全排列字典序生成算法
- 全排列的生成算法 字典序法
- 字典序法生成全排列算法的证明
- 字典序法生成全排列算法的证明
- 全排列的生成算法:字典序法
- 字典序法生成全排列算法的证明
- 全排列的生成算法:字典序法
- 算法练习 - 字符串的全排列(字典序排列)
- 字典序法生成全排列
- 字典序法生成全排列
- 全排列生成法(6种),字典序
- 生成字典序全排列
- 全排列算法之字典序法
- 字典序法算法(全排列, Java)
- UVa 1428
- StringBuffer、ArrayList、HashMap的初始容量、已经如何扩充的总结(适用范围:JDK1.7)
- 如何提升CSS选择器的性能?
- 大数据IMF传奇行动绝密课程第15课:RDD创建内幕彻底解密
- struts2拦截器报错 Struts2 的错误----couldn't clear tomcat cache java.lang.NoSuchFieldException: resourceEnt
- 数组,字符串全排列算法分析(字典序生成法)
- UVA-350 Pseudo-Random Numbers
- 明明的随机数(不重复,排序)+随机数生成
- sql 语句
- Spring Bean装配
- 经典makefile例子
- Java字符串转换为日期和时间比较
- POJ 2387Til the Cows Come Home
- Android Genymotion 配合Charles代理调试