Java 全排列输出算法,比如“ABCD”进行全排列:
ABCD ABDC ACBD ACDB ADBC ADCB BACD BADC BCAD BCDA BDAC BDCA CABD CADB CBAD CBDA CDAB CDBA DABC DACB DBAC DBCA DCAB DCBA
一下试两种思路:
一、代码看着有点懵懵的,一步一步的,太伤脑筋了。。
思路:以ABCD为例,先取出A,然后对BCD进行排列,然后再取出B,对CD进行排列,得到ABCD,ABDC
依次下去....ACBD ACDB.....
import java.util.Date;
/**
* 递归实现全排列
* @author yx
*
* 2017-6-30
*/
public class Test2 {
public static void main(String[] args) {
Date d1 = new Date();
String str = "ABCD";
new Test2().printStr(str);
Date d2 = new Date();
System.out.println(d2.getTime() - d1.getTime());
}
public void printStr(String str) {
int len = str.length();
for (int i=0; i<len; i++) {
String s = String.valueOf(str.charAt(i));
StringBuffer buffer = new StringBuffer(str);
buffer.deleteCharAt(i);
System.out.println(s + buffer);
printStr(s, buffer.toString());
}
}
public void printStr(String start, String str) {
int len = str.length();
for (int i=0; i<len; i++) {
String s = String.valueOf(str.charAt(i));
StringBuffer buffer = new StringBuffer(str);
buffer.deleteCharAt(i);
if (i != 0)
System.out.println(start + s + buffer);
printStr(start + s, buffer.toString());
}
}
}
二、
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date d1 = new Date();
String str = "ABCDEFHGI";
char[] chars = str.toCharArray();
permutation(chars);
Date d2 = new Date();
System.out.println(d2.getTime() - d1.getTime());
}
/** 数组元素的全排列 */
static void permutation(char[] chars) {
permutation(chars, 0, chars.length - 1);
}
/** 数组中从索引begin到索引end之间的子数组参与到全排列 */
static void permutation(char[] chars, int begin, int end) {
if (begin == end) { //只剩最后一个字符时为出口
for (int i = 0; i < chars.length; ++i) {
System.out.print(chars[i]);
}
System.out.println();
} else {
for (int i = begin; i <= end; ++i) { //每个字符依次固定到数组或子数组的第一个
if (canSwap(chars, begin, i)) { //去重
swap(chars, begin, i); //交换
permutation(chars, begin + 1, end); //递归求子数组的全排列
swap(chars, begin, i); //还原
}
}
}
}
static void swap(char[] chars, int from, int to) {
char temp = chars[from];
chars[from] = chars[to];
chars[to] = temp;
}
static boolean canSwap(char[] chars, int begin, int end) {
for (int i = begin; i < end; ++i) {
if (chars[i] == chars[end]) {
return false;
}
}
return true;
}
}
方法一不能排除重复的,比如“ABCDA”,就会出现重复的情况
方法二可以排除这种情况
方法二执行效率不如方法一,当字符串长度为7、8的时候,方法一的速率是方法二的4倍左右