/**
* 字符串排列
*/
public class StringPermutation {
/**
* 打印字符串(字符数组)的全排列。
*
* @param charArray
*/
public static void permutation(char[] charArray) {
if (null == charArray || charArray.length == 0) return;
permutation(charArray, 0);
}
/**
* 将字符数组的全排列打印出来。
*
* <p>
* 全排列的步骤:
* 1)求出所有可能出现在第一个位置的字符。
* 2)每次找到可能出现在第一个位置的字符时,将第一个位置的字符固定,然后求出后面字符的全排列。
* 3)在第2步中,求后面字符的全排列时,我们仍然采用第1步+第2步的方法来实现,故实现全排列的方法显然是一个递归方法。
*
* 举例:abcd的全排列
* 1)a为第一个位置的字符(a与自己交换),然后求bcd的全排列。
* bcd的全排列:
* 1>b为第一个位置的字符(b与自己交换),然后求cd的全排列。
* 2>c为第一个位置的字符(b与c交换),然后求bd的全排列。
* 3>d为第一个位置的字符(b与d交换),然后求d的全排列,因为d后面没有字符了,故这里就是递归的出口,打印字符数组即可。
* 2)b为第一个位置的字符(a与b交换),然后求acd的全排列。
* 3)c为第一个位置的字符(a与c交换),然后求bad的全排列。
* 4)d为第一个位置的字符(a与d交换),然后求bca的全排列。
*
* @param charArray 待排列的字符串
* @param begin 第一个位置的字符
*/
public static void permutation(char[] charArray, int begin) {
// 若第一个位置的字符的后面已经没有字符了,则说明已经到达最深层次的递归方法了,即这里是递归的出口。
if (begin == charArray.length - 1) {
printString(charArray);
}
// 若第一个位置的字符的后面还有字符,则继续调用递归方法。
else {
// 求出所有可能出现在第一个位置的字符
for (int index = begin; index < charArray.length; index++) {
swap(charArray, begin, index); // 将第一个位置的字符与其它字符依次进行交换
permutation(charArray, begin + 1); // 将第一个位置的字符固定,然后求出后面字符的全排列
swap(charArray, begin, index); // 将之前交换的字符交换回来,以便第一个位置的字符与下一个字符进行交换
}
}
}
public static void swap(char[] charArray, int indexA, int indexB) {
if (indexA != indexB) {
char temp = charArray[indexA];
charArray[indexA] = charArray[indexB];
charArray[indexB] = temp;
}
}
public static void printString(char[] charArray) {
System.out.println(charArray);
}
public static void main(String[] args) {
String str = "abcd";
char[] chars = str.toCharArray();
permutation(chars);
}
}