全排列算法实现
方法1:插入法,取字符串的第一个元素放到集合res,后面将字符串的其余元素依次插入到当前集合res的前,中,后。
import java.util.ArrayList;
public class FullPermutation1 {
public static ArrayList<String> f(String s){
ArrayList<String> res = new ArrayList<>() ;
res.add("" + s.charAt(0)) ;
for(int i=1; i<s.length(); i++){
char c = s.charAt(i) ;
ArrayList<String> res1 = new ArrayList<>() ;
for(String s1 : res){
String str = c + s1 ; //插入到当前集合元素的前方
res1.add(str) ;
str = s1 + c ; //插入到当前集合元素的后方
res1.add(str) ;
for(int j=1;j<s1.length(); j++){ //插入到当前集合元素的中间
str = s1.substring(0,j) + c + s1.substring(j) ;
res1.add(str) ;
}
}
res = res1 ; //每插入完成一个元素后更新集合
}
return res ;
}
public static void main(String[] args){
String s = "abcd" ;
System.out.println("全排列的种类有:" + f(s).size()) ;
for(String result : f(s)){
System.out.println(result) ;
}
}
}
方法2:交换法:每个元素尝试着放到头部,每条支路完成后,要回溯恢复为之前的情况
import java.util.ArrayList;
import java.util.Iterator;
public class FullPermutation2 {
public static ArrayList<String> result = new ArrayList<>() ;
public static void swap(char [] arr, int i, int j){
char temp = arr[i] ;
arr[i] = arr[j] ;
arr[j] = temp ;
}
public static void getPermutationCore(char [] arr, int k){
if(k == arr.length){
result.add(new String(arr)) ;
}
for(int i=k; i<arr.length; i++){
swap(arr, i, k) ;
getPermutationCore(arr, k+1) ;
swap(arr, i, k) ; //回溯
}
}
public static ArrayList<String> getPermutation(String s){
char [] res = s.toCharArray() ;
getPermutationCore(res, 0) ;
return result ;
}
public static void main(String[] args){
String s = "abcd" ;
ArrayList<String> result = getPermutation(s) ;
Iterator iterator = result.iterator() ;
while(iterator.hasNext()){
System.out.println(iterator.next()) ;
}
}
}
方法3:前缀法,此方法更使适用,可以输出按字符串升序的全排列,更能满足需求。
public class FullPermutation3 {
public static int count = 0 ;
public static long factorial(long n){//求阶乘
long result = 1 ;
for(long i=1; i<=n; i++){
result *= i ;
}
return result ;
}
public static void getPermutation(String prefix, char [] arr){ //前缀法求全排列
if(prefix.length() == arr.length){
count ++ ;
System.out.println(prefix) ;
if(count == factorial(arr.length)){ //所有全排列输出完毕,则退出
System.exit(0) ;
}
}
for(int i=0; i<arr.length; i++){
char c = arr[i] ;
if(count(arr,c) > count(prefix.toCharArray(),c)){
getPermutation(prefix+c, arr) ; //每个字符分别作为前缀依次递归下去
}
}
}
public static int count(char [] arr, char ch){ //计算字符在字符数组中出现的次数
int sum = 0;
for(int i=0; i<arr.length; i++){
if(arr[i] == ch){
sum ++ ;
}
}
return sum ;
}
public static void main(String[] args){
String s = "abcd" ;
getPermutation("",s.toCharArray());
}
}