差不多半个月没写博客了,今天再写一篇。
字符串全排列相信大家都不陌生,对于我来说真的是写了又忘,忘了又写,所以决定写成一篇博客,废话不多说下面我来分析问题:
问题描述:给定一个字符串写出它的全排列,例如ab,全排列是ab,ba,而abc的全排列abc,acb,bac,bca,cab,cba。
解题思路:我们以具体例子分析,假如abc,如上所示,它的全排列是不是就是把字符串中每一个字符,放在第一位,然后再对剩下的字符串做全排列,如把a放在第一位,剩下bc
全排列是bc,cb,组合起来就是abc,acb,那么把b放在第一位,剩下字符串的排列是ac,ca,组合起来就是,bac,bca。那么把字符串中所有的字符都放在第一位一次,等这些过程全部做完,那么就是一个字符串的全排列。所以这就是一个递归的思路,把字符串分为两部分,第一部分是取出的字符,第二部分是剩下的字符组成的字符串,把第一部分放在第一位,把第二部分的全排列放在第二位。那么怎么把第一部分和第二部分组合起来才是关键,因为第一部分,只是一个字符,第二部分是全排列,是好几个字符串,我的思路是一种字符积累的思路,我们把第一部分积累起来成一个字符串,开始的时候这个字符串是一个空字符串,当我们取出一个字符,把这个字符添加到这个字符串的末尾,然后形成一个新的字符串,这就把第一个字符积累起来了,然后把这个积累起来的字符串当做一个参数,传递给第二部分要做全排列的函数中,第二部分在做全排列的时候,还是把取出的字符加到哪个积累字符串的后面,那么第二部分越拆越短,知道不能拆了,这时候这个积累字符串其实就是全排列中的一个字符串,然后将这个积累字符串输出就好。
下面是我的代码:
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Test {
public static void getFull(String str){
if(str==null){
System.out.println("null");
}else{
getFull(str,"",str.length(),new HashSet<String>());
}
}
private static void getFull(String str,String has,int length,Set<String> set){
for(int i=0;i<str.length();i++){
StringBuilder sb=new StringBuilder();
char single=str.charAt(i);
String front="";
String behind="";
if(i==0){
front="";
behind=str.substring(1);
}else if(i==str.length()-1){
front=str.substring(0, str.length()-1);
behind="";
}else{
front=str.substring(0, i);
behind=str.substring(i+1);
}
sb.append(front);
sb.append(behind);
String temp=has+String.valueOf(single);
if(temp.length()==length){
if(!set.contains(temp)){
set.add(temp);
System.out.println(temp);
}
}
getFull(sb.toString(), temp,length,set);
}
}
public static void main(String[] args) {
getFull("abc");
}