本文考虑了存在相同字符的情况。
实现效果:
输入1212,得到以下字符串:
1212
1221
1122
2112
2121
2211
相关代码:
import java.util.Scanner;
/**
* 字符全排列
* @author 爱西米
*
*/
public class AllPermutation {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.nextLine();
char[] strArr = str.toCharArray();
permute(strArr, 0, strArr.length);
}
/**
* 交换字符在数组中位置
* @param str
* @param a
* @param b
*/
public static void swap(char[] strArr, int a, int b){
char temp = strArr[a];
strArr[a] = strArr[b];
strArr[b] = temp;
}
/**
* 全排列递归算法:
* 第一次循环时,把第一个字符a和a交换位置,得到的仍是abc,先固定第一个字符a,通过递归排列后面两个字符bc:abc,acb,再将abc的位置还原为abc;
* 第二次循环时,把第一个字符a和后面的b交换位置,得到bac,接着固定第一个字符b,通过递归排列后面两个字符ac:bac,bca,再将bac的位置还原为abc;
* 第三次循环时,把第一个字符a和后面的c交换位置,得到cba,接着固定第一个字符c,通过递归排列后面两个字符ba:cba,cab,再将cba的位置还原为abc.
* @param strArr
* @param from
* @param to
*/
public static void permute(char[] strArr, int from, int to){
if((strArr==null) || (from<0) || (from>to)){
return;
}else if(from == to){
System.out.println(strArr);
}else{
for (int i = from; i < to; i++) {
//过滤相同字符
boolean flag = existsSameChar(strArr, from, i);
if(!flag){
continue;
}
swap(strArr, i, from);
permute(strArr, from+1, to);
swap(strArr, i, from);
}
}
}
/**
* 当前字符前是否存在相同字符
* @param strArr
* @param from
* @param currentI
* @return
*/
private static boolean existsSameChar(char[] strArr, int from, int currentI) {
boolean flag = true;//标识前面是否存在与当前字符相同的字符,默认情况下不存在。
int temp = currentI-1;
while(temp >= from){
if(strArr[temp] == strArr[currentI]){
flag = false;//存在相同字符
break;
}
temp--;
}
return flag;
}
}