题目:终端随机输入一串字符串,输出该字符串的所有排列。
例如,输入:“abc”,输出:abc、acb、bac、bca、cab、cba
【解决思想与办法】
正常人的思维是,固定第一个字符,然后依次将后面的字符串与前面的交换,那么排列的个数就是除了第一个字符以外,其他字符的排列个数+1。也就是固定一个字符之后,再将问题变小,只需要求出后面子串的排列个数就可以得出结果,当然第一时间想到的就是递归的算法了。下面这张图很清楚的给出了递归的过程:
很明显,递归的出口,就是只剩一个字符的时候,递归的循环过程,就是从每个子串的第二个字符开始依次与第一个字符交换,然后继续处理子串。还有一点就是可能会有重复数据,有人可能会采取向下比较策略即在交换之前做一次比较查看这两个值是否一样,我觉得大可不必,大不了有重复的,存放这些结果的容器选用HashSet即可,这样不仅降低了程序的复杂度也能提升一定的程序效率,何乐而不为呢!
【关键词提示】
permutation [pɜːmjʊ'teɪʃ(ə)n] 排列,置换 recursion [rɪ'kɜːʃ(ə)n] 递归,循环
具体代码参看如下:
1 import java.util.ArrayList; 2 import java.util.HashSet; 3 import java.util.Scanner; 4 5 public class RecursionPermutation { 6 public static ArrayList<String> result = new ArrayList<String>(); 7 public static HashSet<String> set = new HashSet<String>(); 8 /** 9 * 主函数入口 10 * @param args 11 */ 12 public static void main(String[] args) { 13 System.out.println("请随意输入一串字符串:"); 14 String inputString = new Scanner(System.in).next().toString(); 15 ArrayList<String> result = Permutation(inputString); 16 for (int i = 0; i < result.size(); i++) { 17 System.out.println(result.get(i)); 18 } 19 } 20 21 /** 22 * 递归函数主入口 23 * @param str 24 * @return 25 */ 26 public static ArrayList<String> Permutation(String str) { 27 if (str == null || str.length() == 0) 28 return result; 29 else 30 Permutation(str, 0, str.length() - 1); 31 result.addAll(set); 32 return result; 33 } 34 35 /** 36 * 递归条件函数 37 * @param str 38 * @param start 39 * @param end 40 */ 41 public static void Permutation(String str, int start, int end) { 42 char[] array = str.toCharArray(); 43 String r = null; 44 if (start == end) { 45 r = String.valueOf(array); 46 set.add(r); 47 } else { 48 for (int i = start; i <= end; i++) { 49 char tmp = array[start]; 50 array[start] = array[i]; 51 array[i] = tmp; 52 53 Permutation(String.valueOf(array), start + 1, array.length - 1); 54 55 tmp = array[start]; 56 array[start] = array[i]; 57 array[i] = tmp; 58 } 59 } 60 } 61
以上代码都在本机测试验证通过,绝对保证无误!!!