先看一个题:
题目描述
输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串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。