问题:输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。
输入描述:输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。
解决思路:第一遍将第一个字母固定,遍历所有字母,与第一个字母交换位置,然后固定下一个字母,与其后的所有字母依次交换位置,直到固定最后一个字母。
字符串的全排列是一个概率问题,排除相同字母造成的影响,比如abc的全排列个数为A33 = 6个;
再比如字符串“YONYOU”,先拍出现一次的字母,再排出现两次的字母,一共是A62C42C22,解释如下:有6个位置;先排N ,U有6*5=30种;再排Y,Y只有4个坑了有4*3/2=6种;最后2个位置给O,O,所以总共30*6=180种。
算法采用递归算法:
1 import java.util.ArrayList; 2 import java.util.Collections; 3 4 /** 5 * 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 6 * @author 王任义 7 * 8 */ 9 public class FullPermutation { 10 public static void main(String[] args) { 11 FullPermutation test = new FullPermutation(); 12 System.out.println(test.Permutation("alibaba")); 13 System.out.println(test.count); 14 } 15 public ArrayList<String> Permutation(String str) { 16 ArrayList<String> list = new ArrayList<String>(); 17 PermutationStr(str.toCharArray(),0,list); 18 Collections.sort(list); 19 return list; 20 } 21 public int count = 0; 22 public void PermutationStr(char[] str,int times,ArrayList<String> list){ 23 if(times == str.length-1){ 24 String val = String.valueOf(str); 25 if(!list.contains(val)){ 26 // ++count; 27 // System.out.println(str); 28 list.add(val); 29 } 30 31 }else{ 32 for(int i = times;i<str.length;i++){ 33 swap(str,times,i); 34 PermutationStr(str,times+1,list); 35 swap(str,times,i); 36 } 37 } 38 } 39 private void swap(char[] array,int one,int two){ 40 char tmp = array[one]; 41 array[one] = array[two]; 42 array[two] = tmp; 43 } 44 }
虽然在开始的时候,递归在内存使用的是同一个char数组str,但是每次将递归完成的结果放到list当中的时候,并不是同一个对象,查看源码可以发现,String.valueOf(char[])方法最终是新建了一个数组对象,将参数中的值复制到String对象内置的value数组中。