要求:
字符串的所有排列组合
思路:
函数传入参:每一位可选字符cs数组,当前位置cur,输出的位数,前面的循环所得的子输出str
代码:
public class Main {
public static void main(String [] args) {
char[] cs = {'a','b'};
show(cs,0,3,"");
}
//len:位数
static private void show(char[] cs,int cur,int len,String str){
if (cur==len){
System.out.println(str);
return;
}
for (int i = 0;i<cs.length;i++){
String s = str+cs[i];
show(cs,cur+1,len,s);
}
}
}
要求:
求字符串的全排列
思路:
运用递归的思想,需要全排列的字符串是一个字符串,那么它的子字符串也是一个字符串,要全排列该字符串,可以先全排列它的子字符串,直到子字符串长度为1;
先固定字符串第p个位置的字符,然后全排列p+1位置到末尾的子字符串,然后更换p位置的字符,直到每个字符都在p位置出现一次。
接着p++,p位置往后移动一位,针对新的p位置重复上述操作,直至p指向最后一个字符,这个时候输出当前的字符顺序。
(代码有详细注释,好好体会)
代码:
public class Main {
public static void main(String[] args){
permutation("abc".toCharArray(),0);
}
//全排列数组p位置后面的字符数组
private static void permutation(char[] arr,int p) {
//当p位置指向字符串最后一个位置时,输出当前排列的字符数组
if(p==arr.length-1) {
System.out.println(String.valueOf(arr));
return;
}
//固定p位置的字符,p后面的字符依次和p交换
for(int i=p;i<arr.length;i++) {
swap(arr,i,p);//将第一个字符与后面的字符交换
permutation(arr,p+1);//对p位置后面的字符进行全排列,递归
swap(arr,i,p);//再将之前交换的字符交换回来,以便第一个字符再与其他字符交换
}
}
//数组字符交换函数
private static void swap(char[] charArray,int i,int j)
{
char temp = charArray[i];
charArray[i] = charArray[j];
charArray[j] = temp;
}
}
字符串有重复字符:
解决:
1 直接存到set里面
2 进行交换递归时先判断前面是不是有重复的字符
public class Main {
public static void main(String[] args){
permutation("abba".toCharArray(),0);
}
//全排列数组p位置后面的字符数组
private static void permutation(char[] arr, int p) {
//当p位置指向字符串最后一个位置时,输出当前排列的字符数组
if(p==arr.length-1) {
System.out.println(String.valueOf(arr));
return;
}
//固定p位置的字符,p后面的字符依次和p交换
for(int i=p;i<arr.length;i++) {
if (check(arr,i,p)) continue;
swap(arr, i, p);//将第一个字符与后面的字符交换
permutation(arr, p + 1);//对p位置后面的字符进行全排列,递归
swap(arr, i, p);//再将之前交换的字符交换回来,以便第一个字符再与其他字符交换
}
}
private static boolean check(char[] arr, int index ,int p) {
for (int i = p;i<index;i++){
if (arr[i]==arr[index]) return true;
}
return false;
}
//数组字符交换函数
private static void swap(char[] charArray,int i,int j)
{
char temp = charArray[i];
charArray[i] = charArray[j];
charArray[j] = temp;
}
}
字符串的全排列,按照字典序输出:
1 把所有字符串存到有序的TreeSet里面
2 Collections.sort()
要求:
求字符串的全部组合
方法一:
思路:
最容易想到的方式是递归,遍历字符串,每个字符串只能取或不取。
若取该字符,就把它放到结果字符串中,遍历完毕后,输出结果字符串。
代码:
public class Main {
public static void main(String [] args) {
String s="ABC";
char[] c=s.toCharArray();
StringBuffer sb=new StringBuffer();
//取组合的长度
for(int i=1;i<=c.length;i++) {
permutation(c,0,i,sb);
}
}
/**
* @Description:
* @Param: c:需排列的字符串 p:当前索引字符串位置 len:取组合的长度 sb:保存字符串
* @return:
* @Author: Zhuolinbo
* @date: 2019/8/6 11:07
*/
private static void permutation(char[] c,int p,int len, StringBuffer sb) {
if(len==0) {//当都选择结束时打印sb内容
System.out.println(sb+" ");
return;
}
if(p==c.length) return;
sb.append(c[p]);//取
permutation(c,p+1,len-1,sb);// 剩下的里面选len-1个
sb.deleteCharAt(sb.length()-1);//不取
permutation(c,p+1,len,sb);//剩下的里面选len个
}
}
思路:
把每个字符用一个数位表示,用一个01字符串(或者数组)来表示每一个可能的结果。
1代表取该位置代表的字符,0代表不取。
举例,如求abc的所有组合:a,b,c,ab,ac,bc,abc
a:100
b:010
c:001
ab:110
ac:101
bc:011
abc:111
这些10字符串实际上就是,一个个三位数,每位可能的取值为0或1。
利用第一道题的思想,可以很容易求出这些三位数。
代码:
public class Main {
public static void main(String [] args) {
String str = "abc";
show(0,3,"",str);
}
//len:位数
static private void show(int cur,int len,String str,String str1){
if (cur==len){
char[] c = str.toCharArray();
for (int i = 0;i<c.length;i++){
if (c[i]=='1') System.out.print(str1.charAt(i));
}
System.out.println();
return;
}
for (int i = 0;i<2;i++){
String s = str+i;
show(cur+1,len,s,str1);
}
}
}