代码之家  ›  专栏  ›  技术社区  ›  GurdeepS

生成给定字符串的所有排列

  •  387
  • GurdeepS  · 技术社区  · 14 年前

    找到一根弦的所有排列的优雅方法是什么?例如。 ba ,将是 文学士 ab 但是呢 abcdefgh ?有没有Java实现的例子?

    47 回复  |  直到 5 年前
        1
  •  569
  •   Eric Leschinski Yashu Seth    8 年前
    public static void permutation(String str) { 
        permutation("", str); 
    }
    
    private static void permutation(String prefix, String str) {
        int n = str.length();
        if (n == 0) System.out.println(prefix);
        else {
            for (int i = 0; i < n; i++)
                permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
        }
    }
    

    (通过 Introduction to Programming in Java )

        2
  •  191
  •   Mark Byers    14 年前

    使用递归。

    • 依次尝试将每个字母作为第一个字母,然后使用递归调用查找其余字母的所有排列。
    • 基本情况是,当输入为空字符串时,唯一的排列是空字符串。
        3
  •  62
  •   Uwe Plonus    6 年前

    以下是我的解决方案,基于“破解编码采访”(第54页)这本书的理念:

    /**
     * List permutations of a string.
     * 
     * @param s the input string
     * @return  the list of permutations
     */
    public static ArrayList<String> permutation(String s) {
        // The result
        ArrayList<String> res = new ArrayList<String>();
        // If input string's length is 1, return {s}
        if (s.length() == 1) {
            res.add(s);
        } else if (s.length() > 1) {
            int lastIndex = s.length() - 1;
            // Find out the last character
            String last = s.substring(lastIndex);
            // Rest of the string
            String rest = s.substring(0, lastIndex);
            // Perform permutation on the rest string and
            // merge with the last character
            res = merge(permutation(rest), last);
        }
        return res;
    }
    
    /**
     * @param list a result of permutation, e.g. {"ab", "ba"}
     * @param c    the last character
     * @return     a merged new list, e.g. {"cab", "acb" ... }
     */
    public static ArrayList<String> merge(ArrayList<String> list, String c) {
        ArrayList<String> res = new ArrayList<>();
        // Loop through all the string in the list
        for (String s : list) {
            // For each string, insert the last character to all possible positions
            // and add them to the new list
            for (int i = 0; i <= s.length(); ++i) {
                String ps = new StringBuffer(s).insert(i, c).toString();
                res.add(ps);
            }
        }
        return res;
    }
    

    运行字符串“abcd”的输出:

    • 步骤1:合并[A]和B: [巴,阿瑟]

    • 第二步:合并[BA,AB]和C: 【CBA、BCA、BAC、CAB、ACB、ABC】

    • 第三步:合并[CBA、BCA、BAC、CAB、ACB、ABC]和D: [DCBA、CDBA、CBDA、CBAD、DBCA、BDCA、BCDA、BCAD、DBAC、BDAC、BADC、BACD、DCAB、CDAB、CADB、CABD、DACB、ADCB、ACDB、ACBD、DABC、ADBC、ABDC、ABCD]

        4
  •  48
  •   ric    6 年前

    在这里和其他论坛给出的所有解决方案中,我最喜欢马克·拜尔斯。这种描述实际上让我自己思考和编写代码。 太糟糕了,我不能吐出他的解决方案,因为我是新手。
    不管怎样,这是我对他的描述的实现

    public class PermTest {
    
        public static void main(String[] args) throws Exception {
            String str = "abcdef";
            StringBuffer strBuf = new StringBuffer(str);
            doPerm(strBuf,str.length());
        }
    
        private static void doPerm(StringBuffer str, int index){
    
            if(index <= 0)
                System.out.println(str);            
            else { //recursively solve this by placing all other chars at current first pos
                doPerm(str, index-1);
                int currPos = str.length()-index;
                for (int i = currPos+1; i < str.length(); i++) {//start swapping all other chars with current first char
                    swap(str,currPos, i);
                    doPerm(str, index-1);
                    swap(str,i, currPos);//restore back my string buffer
                }
            }
        }
    
        private  static void swap(StringBuffer str, int pos1, int pos2){
            char t1 = str.charAt(pos1);
            str.setCharAt(pos1, str.charAt(pos2));
            str.setCharAt(pos2, t1);
        }
    }   
    

    我更喜欢在这个线程的第一个解决方案之前使用这个解决方案,因为这个解决方案使用了StringBuffer。我不会说我的解决方案没有创建任何临时字符串(它实际上在 system.out.println 在哪里 toString() 调用了StringBuffer)。但我觉得这比第一个创建了太多字符串的解决方案要好。可能有一些性能人员可以用“内存”来评估这个问题(对于“时间”来说,它已经因为额外的“交换”而滞后了)

        5
  •  20
  •   devastator    11 年前

    Java中的一个非常基本的解决方案是使用递归+SET(避免重复),如果您想存储和返回解决方案字符串:

    public static Set<String> generatePerm(String input)
    {
        Set<String> set = new HashSet<String>();
        if (input == "")
            return set;
    
        Character a = input.charAt(0);
    
        if (input.length() > 1)
        {
            input = input.substring(1);
    
            Set<String> permSet = generatePerm(input);
    
            for (String x : permSet)
            {
                for (int i = 0; i <= x.length(); i++)
                {
                    set.add(x.substring(0, i) + a + x.substring(i));
                }
            }
        }
        else
        {
            set.add(a + "");
        }
        return set;
    }
    
        6
  •  15
  •   grepit    9 年前

    所有以前的贡献者都在解释和提供代码方面做得很好。我想我也应该分享这种方法,因为它可能也会帮助别人。解决方案基于( heaps' algorithm )

    以下几点:

    1. 注意,Excel中描述的最后一项只是为了帮助您更好地可视化逻辑。所以,最后一列中的实际值是2,1,0(如果我们运行代码是因为我们处理的是数组,而数组从0开始)。

    2. 交换算法基于当前位置的偶数或奇数值进行。如果您查看调换方法的调用位置,这是非常不言而喻的。您可以看到发生了什么。

    以下是发生的情况: enter image description here

    public static void main(String[] args) {
    
            String ourword = "abc";
            String[] ourArray = ourword.split("");
            permute(ourArray, ourArray.length);
    
        }
    
        private static void swap(String[] ourarray, int right, int left) {
            String temp = ourarray[right];
            ourarray[right] = ourarray[left];
            ourarray[left] = temp;
        }
    
        public static void permute(String[] ourArray, int currentPosition) {
            if (currentPosition == 1) {
                System.out.println(Arrays.toString(ourArray));
            } else {
                for (int i = 0; i < currentPosition; i++) {
                    // subtract one from the last position (here is where you are
                    // selecting the the next last item 
                    permute(ourArray, currentPosition - 1);
    
                    // if it's odd position
                    if (currentPosition % 2 == 1) {
                        swap(ourArray, 0, currentPosition - 1);
                    } else {
                        swap(ourArray, i, currentPosition - 1);
                    }
                }
            }
        }
    
        7
  •  11
  •   Jorge Israel Peña    10 年前

    这个没有递归

    public static void permute(String s) {
        if(null==s || s.isEmpty()) {
            return;
        }
    
        // List containing words formed in each iteration 
        List<String> strings = new LinkedList<String>();
        strings.add(String.valueOf(s.charAt(0))); // add the first element to the list
    
         // Temp list that holds the set of strings for 
         //  appending the current character to all position in each word in the original list
        List<String> tempList = new LinkedList<String>(); 
    
        for(int i=1; i< s.length(); i++) {
    
            for(int j=0; j<strings.size(); j++) {
                tempList.addAll(merge(s.charAt(i), strings.get(j)));
                            }
            strings.removeAll(strings);
            strings.addAll(tempList);
    
            tempList.removeAll(tempList);
    
        }
    
        for(int i=0; i<strings.size(); i++) {
            System.out.println(strings.get(i));
        }
    }
    
    /**
     * helper method that appends the given character at each position in the given string 
     * and returns a set of such modified strings 
     * - set removes duplicates if any(in case a character is repeated)
     */
    private static Set<String> merge(Character c,  String s) {
        if(s==null || s.isEmpty()) {
            return null;
        }
    
        int len = s.length();
        StringBuilder sb = new StringBuilder();
        Set<String> list = new HashSet<String>();
    
        for(int i=0; i<= len; i++) {
            sb = new StringBuilder();
            sb.append(s.substring(0, i) + c + s.substring(i, len));
            list.add(sb.toString());
        }
    
        return list;
    }
    
        8
  •  9
  •   Bernhard Barker    10 年前

    让我们使用输入 abc 举个例子。

    从最后一个元素开始( c )在一个集合中( ["c"] ,然后添加第二个最后一个元素( b )在它的前面,末端和中间的每一个可能的位置,使它 ["bc", "cb"] 然后以同样的方式从后面添加下一个元素( a )到集合中的每个字符串,使其成为:

    "a" + "bc" = ["abc", "bac", "bca"]  and  "a" + "cb" = ["acb" ,"cab", "cba"] 
    

    因此,整个排列:

    ["abc", "bac", "bca","acb" ,"cab", "cba"]
    

    代码:

    public class Test 
    {
        static Set<String> permutations;
        static Set<String> result = new HashSet<String>();
    
        public static Set<String> permutation(String string) {
            permutations = new HashSet<String>();
    
            int n = string.length();
            for (int i = n - 1; i >= 0; i--) 
            {
                shuffle(string.charAt(i));
            }
            return permutations;
        }
    
        private static void shuffle(char c) {
            if (permutations.size() == 0) {
                permutations.add(String.valueOf(c));
            } else {
                Iterator<String> it = permutations.iterator();
                for (int i = 0; i < permutations.size(); i++) {
    
                    String temp1;
                    for (; it.hasNext();) {
                        temp1 = it.next();
                        for (int k = 0; k < temp1.length() + 1; k += 1) {
                            StringBuilder sb = new StringBuilder(temp1);
    
                            sb.insert(k, c);
    
                            result.add(sb.toString());
                        }
                    }
                }
                permutations = result;
                //'result' has to be refreshed so that in next run it doesn't contain stale values.
                result = new HashSet<String>();
            }
        }
    
        public static void main(String[] args) {
            Set<String> result = permutation("abc");
    
            System.out.println("\nThere are total of " + result.size() + " permutations:");
            Iterator<String> it = result.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }
        }
    }
    
        9
  •  8
  •   Adilli Adil    9 年前

    这里有一个优雅的,非递归的,o(n!)解决方案:

    public static StringBuilder[] permutations(String s) {
            if (s.length() == 0)
                return null;
            int length = fact(s.length());
            StringBuilder[] sb = new StringBuilder[length];
            for (int i = 0; i < length; i++) {
                sb[i] = new StringBuilder();
            }
            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                int times = length / (i + 1);
                for (int j = 0; j < times; j++) {
                    for (int k = 0; k < length / times; k++) {
                        sb[j * length / times + k].insert(k, ch);
                    }
                }
            }
            return sb;
        }
    
        10
  •  5
  •   Katie    9 年前

    一个简单的解决方案是使用两个指针递归地交换字符。

    public static void main(String[] args)
    {
        String str="abcdefgh";
        perm(str);
    }
    public static void perm(String str)
    {  char[] char_arr=str.toCharArray();
        helper(char_arr,0);
    }
    public static void helper(char[] char_arr, int i)
    {
        if(i==char_arr.length-1)
        {
            // print the shuffled string 
                String str="";
                for(int j=0; j<char_arr.length; j++)
                {
                    str=str+char_arr[j];
                }
                System.out.println(str);
        }
        else
        {
        for(int j=i; j<char_arr.length; j++)
        {
            char tmp = char_arr[i];
            char_arr[i] = char_arr[j];
            char_arr[j] = tmp;
            helper(char_arr,i+1);
            char tmp1 = char_arr[i];
            char_arr[i] = char_arr[j];
            char_arr[j] = tmp1;
        }
    }
    }
    
        11
  •  4
  •   Tunaki    8 年前

    这对我很有用……

    import java.util.Arrays;
    
    public class StringPermutations{
        public static void main(String args[]) {
            String inputString = "ABC";
            permute(inputString.toCharArray(), 0, inputString.length()-1);
        }
    
        public static void permute(char[] ary, int startIndex, int endIndex) {
            if(startIndex == endIndex){
                System.out.println(String.valueOf(ary));
            }else{
                for(int i=startIndex;i<=endIndex;i++) {
                     swap(ary, startIndex, i );
                     permute(ary, startIndex+1, endIndex);
                     swap(ary, startIndex, i );
                }
            }
        }
    
        public static void swap(char[] ary, int x, int y) {
            char temp = ary[x];
            ary[x] = ary[y];
            ary[y] = temp;
        }
    }
    
        12
  •  4
  •   riteshkasat    8 年前

    python实现

    def getPermutation(s, prefix=''):
            if len(s) == 0:
                    print prefix
            for i in range(len(s)):
                    getPermutation(s[0:i]+s[i+1:len(s)],prefix+s[i] )
    
    
    
    getPermutation('abcd','')
    
        13
  •  3
  •   Jared Burrows    9 年前

    使用递归。

    当输入为空字符串时,唯一的排列是空字符串。尝试将字符串中的每个字母设为第一个字母,然后使用递归调用查找其余字母的所有排列。

    import java.util.ArrayList;
    import java.util.List;
    
    class Permutation {
        private static List<String> permutation(String prefix, String str) {
            List<String> permutations = new ArrayList<>();
            int n = str.length();
            if (n == 0) {
                permutations.add(prefix);
            } else {
                for (int i = 0; i < n; i++) {
                    permutations.addAll(permutation(prefix + str.charAt(i), str.substring(i + 1, n) + str.substring(0, i)));
                }
            }
            return permutations;
        }
    
        public static void main(String[] args) {
            List<String> perms = permutation("", "abcd");
    
            String[] array = new String[perms.size()];
            for (int i = 0; i < perms.size(); i++) {
                array[i] = perms.get(i);
            }
    
            int x = array.length;
    
            for (final String anArray : array) {
                System.out.println(anArray);
            }
        }
    }
    
        14
  •  2
  •   Antony Johnson    11 年前
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Scanner;
    public class hello {
        public static void main(String[] args) throws IOException {
            hello h = new hello();
            h.printcomp();
        }
          int fact=1;
        public void factrec(int a,int k){
            if(a>=k)
            {fact=fact*k;
            k++;
            factrec(a,k);
            }
            else
            {System.out.println("The string  will have "+fact+" permutations");
            }
            }
        public void printcomp(){
            String str;
            int k;
            Scanner in = new Scanner(System.in);
            System.out.println("enter the string whose permutations has to b found");
            str=in.next();
            k=str.length();
            factrec(k,1);
            String[] arr =new String[fact];
            char[] array = str.toCharArray();
            while(p<fact)
            printcomprec(k,array,arr);
                // if incase u need array containing all the permutation use this
                //for(int d=0;d<fact;d++)         
            //System.out.println(arr[d]);
        }
        int y=1;
        int p = 0;
        int g=1;
        int z = 0;
        public void printcomprec(int k,char array[],String arr[]){
            for (int l = 0; l < k; l++) {
                for (int b=0;b<k-1;b++){
                for (int i=1; i<k-g; i++) {
                    char temp;
                    String stri = "";
                    temp = array[i];
                    array[i] = array[i + g];
                    array[i + g] = temp;
                    for (int j = 0; j < k; j++)
                        stri += array[j];
                    arr[z] = stri;
                    System.out.println(arr[z] + "   " + p++);
                    z++;
                }
                }
                char temp;
                temp=array[0];
                array[0]=array[y];
                array[y]=temp;
                if (y >= k-1)
                    y=y-(k-1);
                else
                    y++;
            }
            if (g >= k-1)
                g=1;
            else
                g++;
        }
    
    }
    
        15
  •  2
  •   Barzee    11 年前
    /** Returns an array list containing all
     * permutations of the characters in s. */
    public static ArrayList<String> permute(String s) {
        ArrayList<String> perms = new ArrayList<>();
        int slen = s.length();
        if (slen > 0) {
            // Add the first character from s to the perms array list.
            perms.add(Character.toString(s.charAt(0)));
    
            // Repeat for all additional characters in s.
            for (int i = 1;  i < slen;  ++i) {
    
                // Get the next character from s.
                char c = s.charAt(i);
    
                // For each of the strings currently in perms do the following:
                int size = perms.size();
                for (int j = 0;  j < size;  ++j) {
    
                    // 1. remove the string
                    String p = perms.remove(0);
                    int plen = p.length();
    
                    // 2. Add plen + 1 new strings to perms.  Each new string
                    //    consists of the removed string with the character c
                    //    inserted into it at a unique location.
                    for (int k = 0;  k <= plen;  ++k) {
                        perms.add(p.substring(0, k) + c + p.substring(k));
                    }
                }
            }
        }
        return perms;
    }
    
        16
  •  2
  •   Jay Taylor shabeer90    11 年前

    这里有一个简单的Java递归解决方案:

    public static ArrayList<String> permutations(String s) {
        ArrayList<String> out = new ArrayList<String>();
        if (s.length() == 1) {
            out.add(s);
            return out;
        }
        char first = s.charAt(0);
        String rest = s.substring(1);
        for (String permutation : permutations(rest)) {
            out.addAll(insertAtAllPositions(first, permutation));
        }
        return out;
    }
    public static ArrayList<String> insertAtAllPositions(char ch, String s) {
        ArrayList<String> out = new ArrayList<String>();
        for (int i = 0; i <= s.length(); ++i) {
            String inserted = s.substring(0, i) + ch + s.substring(i);
            out.add(inserted);
        }
        return out;
    }
    
        17
  •  2
  •   Shabbir Essaji    8 年前

    这是我通过对置换和递归函数调用的基本理解所做的。需要一点时间,但这是独立完成的。

    public class LexicographicPermutations {
    
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String s="abc";
        List<String>combinations=new ArrayList<String>();
        combinations=permutations(s);
        Collections.sort(combinations);
        System.out.println(combinations);
    }
    
    private static List<String> permutations(String s) {
        // TODO Auto-generated method stub
        List<String>combinations=new ArrayList<String>();
        if(s.length()==1){
            combinations.add(s);
        }
        else{
            for(int i=0;i<s.length();i++){
                List<String>temp=permutations(s.substring(0, i)+s.substring(i+1));
                for (String string : temp) {
                    combinations.add(s.charAt(i)+string);
                }
            }
        }
        return combinations;
    }}
    

    它产生 产量 作为 [abc, acb, bac, bca, cab, cba] .

    它背后的基本逻辑是

    对于每个字符,将其视为第一个字符并查找其余字符的组合。例如 [abc](Combination of abc)-> .

    1. a->[bc](a x Combination of (bc))->{abc,acb}
    2. b->[ac](b x Combination of (ac))->{bac,bca}
    3. c->[ab](c x Combination of (ab))->{cab,cba}

    然后递归地调用 [bc] , [ac] 和; [ab] 独立地。

        18
  •  2
  •   Hadi Elmougy    7 年前

    无递归的Java实现

    public Set<String> permutate(String s){
        Queue<String> permutations = new LinkedList<String>();
        Set<String> v = new HashSet<String>();
        permutations.add(s);
    
        while(permutations.size()!=0){
            String str = permutations.poll();
            if(!v.contains(str)){
                v.add(str);
                for(int i = 0;i<str.length();i++){
                    String c = String.valueOf(str.charAt(i));
                    permutations.add(str.substring(i+1) + c +  str.substring(0,i));
                }
            }
        }
        return v;
    }
    
        19
  •  2
  •   Louis Tsai    6 年前

    让我试着用Kotlin来解决这个问题:

    fun <T> List<T>.permutations(): List<List<T>> {
        //escape case
        if (this.isEmpty()) return emptyList()
    
        if (this.size == 1) return listOf(this)
    
        if (this.size == 2) return listOf(listOf(this.first(), this.last()), listOf(this.last(), this.first()))
    
        //recursive case
        return this.flatMap { lastItem ->
            this.minus(lastItem).permutations().map { it.plus(lastItem) }
        }
    }
    

    核心概念:将长列表分解为小列表+递归

    带示例列表的长答案[1、2、3、4]:

    即使是对于一个4的列表,试图列出你头脑中所有可能的排列也会让人困惑,我们需要做的就是避免这种情况发生。对于我们来说,很容易理解如何对大小为0、1和2的列表进行所有排列,因此我们需要做的就是将它们分解为这些大小中的任何一个,并将它们正确地组合起来。想象一下一台Jackpot机器:这个算法将从右向左旋转,然后写下

    1. 当列表大小为0或1时返回空/1的列表
    2. 当列表大小为2时处理(例如[3,4]),并生成2个排列([3,4]&[4,3])
    3. 对于每个项目,将其标记为最后一个项目中的最后一个,并查找列表中项目其余部分的所有排列。(例如,把[4]放在桌子上,再把[1,2,3]按顺序排列)
    4. 现在,对于所有排列,它都是孩子,将自己放回列表的末尾(例如:[1,2,3][,4],[1,3,2][,4],[2,3,1][,4]…)
        20
  •  1
  •   Andrew Schulman    10 年前
    //Rotate and create words beginning with all letter possible and push to stack 1
    
    //Read from stack1 and for each word create words with other letters at the next location by rotation and so on 
    
    /*  eg : man
    
        1. push1 - man, anm, nma
        2. pop1 - nma ,  push2 - nam,nma
           pop1 - anm ,  push2 - amn,anm
           pop1 - man ,  push2 - mna,man
    */
    
    public class StringPermute {
    
        static String str;
        static String word;
        static int top1 = -1;
        static int top2 = -1;
        static String[] stringArray1;
        static String[] stringArray2;
        static int strlength = 0;
    
        public static void main(String[] args) throws IOException {
            System.out.println("Enter String : ");
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader bfr = new BufferedReader(isr);
            str = bfr.readLine();
            word = str;
            strlength = str.length();
            int n = 1;
            for (int i = 1; i <= strlength; i++) {
                n = n * i;
            }
            stringArray1 = new String[n];
            stringArray2 = new String[n];
            push(word, 1);
            doPermute();
            display();
        }
    
        public static void push(String word, int x) {
            if (x == 1)
                stringArray1[++top1] = word;
            else
                stringArray2[++top2] = word;
        }
    
        public static String pop(int x) {
            if (x == 1)
                return stringArray1[top1--];
            else
                return stringArray2[top2--];
        }
    
        public static void doPermute() {
    
            for (int j = strlength; j >= 2; j--)
                popper(j);
    
        }
    
        public static void popper(int length) {
            // pop from stack1 , rotate each word n times and push to stack 2
            if (top1 > -1) {
                while (top1 > -1) {
                    word = pop(1);
                    for (int j = 0; j < length; j++) {
                        rotate(length);
                        push(word, 2);
                    }
                }
            }
            // pop from stack2 , rotate each word n times w.r.t position and push to
            // stack 1
            else {
                while (top2 > -1) {
                    word = pop(2);
                    for (int j = 0; j < length; j++) {
                        rotate(length);
                        push(word, 1);
                    }
                }
            }
    
        }
    
        public static void rotate(int position) {
            char[] charstring = new char[100];
            for (int j = 0; j < word.length(); j++)
                charstring[j] = word.charAt(j);
    
            int startpos = strlength - position;
            char temp = charstring[startpos];
            for (int i = startpos; i < strlength - 1; i++) {
                charstring[i] = charstring[i + 1];
            }
            charstring[strlength - 1] = temp;
            word = new String(charstring).trim();
        }
    
        public static void display() {
            int top;
            if (top1 > -1) {
                while (top1 > -1)
                    System.out.println(stringArray1[top1--]);
            } else {
                while (top2 > -1)
                    System.out.println(stringArray2[top2--]);
            }
        }
    }
    
        21
  •  1
  •   Bernhard Barker    10 年前

    我们可以使用factorial来查找有多少字符串以特定的字母开头。

    示例:接受输入 abcd (3!) == 6 字符串将以每个字母开头 ABCD .

    static public int facts(int x){
        int sum = 1;
        for (int i = 1; i < x; i++) {
            sum *= (i+1);
        }
        return sum;
    }
    
    public static void permutation(String str) {
        char[] str2 = str.toCharArray();
        int n = str2.length;
        int permutation = 0;
        if (n == 1) {
            System.out.println(str2[0]);
        } else if (n == 2) {
            System.out.println(str2[0] + "" + str2[1]);
            System.out.println(str2[1] + "" + str2[0]);
        } else {
            for (int i = 0; i < n; i++) {
                if (true) {
                    char[] str3 = str.toCharArray();
                    char temp = str3[i];
                    str3[i] = str3[0];
                    str3[0] = temp;
                    str2 = str3;
                }
    
                for (int j = 1, count = 0; count < facts(n-1); j++, count++) {
                    if (j != n-1) {
                        char temp1 = str2[j+1];
                        str2[j+1] = str2[j];
                        str2[j] = temp1;
                    } else {
                        char temp1 = str2[n-1];
                        str2[n-1] = str2[1];
                        str2[1] = temp1;
                        j = 1;
                    } // end of else block
                    permutation++;
                    System.out.print("permutation " + permutation + " is   -> ");
                    for (int k = 0; k < n; k++) {
                        System.out.print(str2[k]);
                    } // end of loop k
                    System.out.println();
                } // end of loop j
            } // end of loop i
        }
    }
    
        22
  •  1
  •   Community Ian Goodfellow    7 年前

    递归 不需要,即使你可以计算 任何直接排列 ,此解决方案使用泛型排列任何数组。

    Here 是关于这个算法的一个很好的信息。

    为了 丙二醇 开发者 here 更有用的实现。

    public static void main(String[] args) {
        String word = "12345";
    
        Character[] array = ArrayUtils.toObject(word.toCharArray());
        long[] factorials = Permutation.getFactorials(array.length + 1);
    
        for (long i = 0; i < factorials[array.length]; i++) {
            Character[] permutation = Permutation.<Character>getPermutation(i, array, factorials);
            printPermutation(permutation);
        }
    }
    
    private static void printPermutation(Character[] permutation) {
        for (int i = 0; i < permutation.length; i++) {
            System.out.print(permutation[i]);
        }
        System.out.println();
    }
    

    这个算法有 o(n) 时间 空间 每种计算的复杂性 置换 .

    public class Permutation {
        public static <T> T[] getPermutation(long permutationNumber, T[] array, long[] factorials) {
            int[] sequence = generateSequence(permutationNumber, array.length - 1, factorials);
            T[] permutation = generatePermutation(array, sequence);
    
            return permutation;
        }
    
        public static <T> T[] generatePermutation(T[] array, int[] sequence) {
            T[] clone = array.clone();
    
            for (int i = 0; i < clone.length - 1; i++) {
                swap(clone, i, i + sequence[i]);
            }
    
            return clone;
        }
    
        private static int[] generateSequence(long permutationNumber, int size, long[] factorials) {
            int[] sequence = new int[size];
    
            for (int j = 0; j < sequence.length; j++) {
                long factorial = factorials[sequence.length - j];
                sequence[j] = (int) (permutationNumber / factorial);
                permutationNumber = (int) (permutationNumber % factorial);
            }
    
            return sequence;
        }
    
        private static <T> void swap(T[] array, int i, int j) {
            T t = array[i];
            array[i] = array[j];
            array[j] = t;
        }
    
        public static long[] getFactorials(int length) {
            long[] factorials = new long[length];
            long factor = 1;
    
            for (int i = 0; i < length; i++) {
                factor *= i <= 1 ? 1 : i;
                factorials[i] = factor;
            }
    
            return factorials;
        }
    }
    
        23
  •  1
  •   Gaurav Jeswani    8 年前

    字符串排列:

    public static void main(String args[]) {
        permu(0,"ABCD");
    }
    
    static void permu(int fixed,String s) {
        char[] chr=s.toCharArray();
        if(fixed==s.length())
            System.out.println(s);
        for(int i=fixed;i<s.length();i++) {
            char c=chr[i];
            chr[i]=chr[fixed];
            chr[fixed]=c;
            permu(fixed+1,new String(chr));
        }   
    }
    
        24
  •  1
  •   Soudipta Dutta    6 年前

    这是另一种更简单的字符串排列方法。

    public class Solution4 {
    public static void main(String[] args) {
        String  a = "Protijayi";
      per(a, 0);
    
    }
    
    static void per(String a  , int start ) {
          //bse case;
        if(a.length() == start) {System.out.println(a);}
        char[] ca = a.toCharArray();
        //swap 
        for (int i = start; i < ca.length; i++) {
            char t = ca[i];
            ca[i] = ca[start];
            ca[start] = t;
            per(new String(ca),start+1);
        }
    
    }//per
    
    }
    
        25
  •  1
  •   Paul92    6 年前

    一个Java实现,用于打印给定字符串的所有排列,考虑重复字符和打印唯一字符,如下:

    import java.util.Set;
    import java.util.HashSet;
    
    public class PrintAllPermutations2
    {
        public static void main(String[] args)
        {
            String str = "AAC";
    
        PrintAllPermutations2 permutation = new PrintAllPermutations2();
    
        Set<String> uniqueStrings = new HashSet<>();
    
        permutation.permute("", str, uniqueStrings);
    }
    
    void permute(String prefixString, String s, Set<String> set)
    {
        int n = s.length();
    
        if(n == 0)
        {
            if(!set.contains(prefixString))
            {
                System.out.println(prefixString);
                set.add(prefixString);
            }
        }
        else
        {
            for(int i=0; i<n; i++)
            {
                permute(prefixString + s.charAt(i), s.substring(0,i) + s.substring(i+1,n), set);
            }
        }
    }
    }
    
        26
  •  0
  •   David Lee    11 年前

    //将每个字符插入到数组列表中

    static ArrayList al = new ArrayList();
    
    private static void findPermutation (String str){
        for (int k = 0; k < str.length(); k++) {
            addOneChar(str.charAt(k));
        }
    }
    
    //insert one char into ArrayList
    private static void addOneChar(char ch){
        String lastPerStr;
        String tempStr;
        ArrayList locAl = new ArrayList();
        for (int i = 0; i < al.size(); i ++ ){
            lastPerStr = al.get(i).toString();
            //System.out.println("lastPerStr: " + lastPerStr);
            for (int j = 0; j <= lastPerStr.length(); j++) {
                tempStr = lastPerStr.substring(0,j) + ch + 
                        lastPerStr.substring(j, lastPerStr.length());
                locAl.add(tempStr);
                //System.out.println("tempStr: " + tempStr);
            }
        }
        if(al.isEmpty()){
            al.add(ch);
        } else {
            al.clear();
            al = locAl;
        }
    }
    
    private static void printArrayList(ArrayList al){
        for (int i = 0; i < al.size(); i++) {
            System.out.print(al.get(i) + "  ");
        }
    }
    
        27
  •  0
  •   nnc    10 年前
    /*
         * eg: abc =>{a,bc},{b,ac},{c,ab}
         * =>{ca,b},{cb,a}
         * =>cba,cab
         * =>{ba,c},{bc,a}
         * =>bca,bac
         * =>{ab,c},{ac,b}
         * =>acb,abc
         */
        public void nonRecpermute(String prefix, String word)
        {
            String[] currentstr ={prefix,word};
            Stack<String[]> stack = new Stack<String[]>();
            stack.add(currentstr);
            while(!stack.isEmpty())
            {
                currentstr = stack.pop();
                String currentPrefix = currentstr[0];
                String currentWord = currentstr[1];
                if(currentWord.equals(""))
                {
                    System.out.println("Word ="+currentPrefix);
                }
                for(int i=0;i<currentWord.length();i++)
                {
                    String[] newstr = new String[2];
                    newstr[0]=currentPrefix + String.valueOf(currentWord.charAt(i));
                    newstr[1] = currentWord.substring(0, i);
                    if(i<currentWord.length()-1)
                    {
                        newstr[1] = newstr[1]+currentWord.substring(i+1);
                    }
                    stack.push(newstr);
                }
    
            }
    
        }
    
        28
  •  0
  •   Bernhard Barker    10 年前

    这可以通过在前面部分结果的所有位置依次插入字符串的每个字母来迭代完成。

    我们从 [A] ,其中 B 变成 [BA, AB] C , [CBA, BCA, BAC, CAB, etc]

    运行时间是 O(n!) ,对于测试用例 ABCD 1 x 2 x 3 x 4

    在上述产品中, 1 是为了 A , the 2 是为了 等。

    镖样品:

    void main() {
    
      String insertAt(String a, String b, int index)
      {
        return a.substring(0, index) + b + a.substring(index);
      }
    
      List<String> Permute(String word) {
    
        var letters = word.split('');
    
        var p_list = [ letters.first ];
    
        for (var c in letters.sublist(1)) {
    
          var new_list = [ ];
    
          for (var p in p_list)
            for (int i = 0; i <= p.length; i++)
              new_list.add(insertAt(p, c, i));
    
          p_list = new_list;
        }
    
        return p_list;
      }
    
      print(Permute("ABCD"));
    
    }
    
        29
  •  0
  •   NNP    10 年前

    以下是两个C版本(仅供参考): 1。打印所有排列 2。返回所有排列

    该算法的基本要点是(可能下面的代码更直观-不过,下面的代码可以做一些解释): -从当前索引到集合的其余部分,在当前索引处交换元素 -从下一个索引递归获取其余元素的排列 -通过重新交换恢复顺序

    注意:上面的递归函数将从开始索引调用。

    private void PrintAllPermutations(int[] a, int index, ref int count)
            {
                if (index == (a.Length - 1))
                {
                    count++;
                    var s = string.Format("{0}: {1}", count, string.Join(",", a));
                    Debug.WriteLine(s);
                }
                for (int i = index; i < a.Length; i++)
                {
                    Utilities.swap(ref a[i], ref a[index]);
                    this.PrintAllPermutations(a, index + 1, ref count);
                    Utilities.swap(ref a[i], ref a[index]);
                }
            }
            private int PrintAllPermutations(int[] a)
            {
                a.ThrowIfNull("a");
                int count = 0;
                this.PrintAllPermutations(a, index:0, count: ref count);
                return count;
            }
    

    版本2(与上面相同-但返回排列而不是打印)

    private int[][] GetAllPermutations(int[] a, int index)
            {
                List<int[]> permutations = new List<int[]>();
                if (index == (a.Length - 1))
                {
                    permutations.Add(a.ToArray());
                }
    
                for (int i = index; i < a.Length; i++)
                {
                    Utilities.swap(ref a[i], ref a[index]);
                    var r = this.GetAllPermutations(a, index + 1);
                    permutations.AddRange(r);
                    Utilities.swap(ref a[i], ref a[index]);
                }
                return permutations.ToArray();
            }
            private int[][] GetAllPermutations(int[] p)
            {
                p.ThrowIfNull("p");
                return this.GetAllPermutations(p, 0);
            }
    

    单元测试

    [TestMethod]
            public void PermutationsTests()
            {
                List<int> input = new List<int>();
                int[] output = { 0, 1, 2, 6, 24, 120 };
                for (int i = 0; i <= 5; i++)
                {
                    if (i != 0)
                    {
                        input.Add(i);
                    }
                    Debug.WriteLine("================PrintAllPermutations===================");
                    int count = this.PrintAllPermutations(input.ToArray());
                    Assert.IsTrue(count == output[i]);
                    Debug.WriteLine("=====================GetAllPermutations=================");
                    var r = this.GetAllPermutations(input.ToArray());
                    Assert.IsTrue(count == r.Length);
                    for (int j = 1; j <= r.Length;j++ )
                    {
                        string s = string.Format("{0}: {1}", j,
                            string.Join(",", r[j - 1]));
                        Debug.WriteLine(s);
                    }
                    Debug.WriteLine("No.OfElements: {0}, TotalPerms: {1}", i, count);
                }
            }
    
        30
  •  0
  •   Sahil Chhabra    10 年前

    这里是一个Java实现:

    /* All Permutations of a String */
    
    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    /* Complexity O(n*n!) */
    class Ideone
    {
         public static ArrayList<String> strPerm(String str, ArrayList<String> list)
         {
            int len = str.length();
            if(len==1){
                list.add(str);
                return list;
            }
    
            list = strPerm(str.substring(0,len-1),list);
            int ls = list.size();
            char ap = str.charAt(len-1);
            for(int i=0;i<ls;i++){
                String temp = list.get(i);
                int tl = temp.length();
                for(int j=0;j<=tl;j++){
                    list.add(temp.substring(0,j)+ap+temp.substring(j,tl));  
                }
            }
    
            while(true){
                String temp = list.get(0);
                if(temp.length()<len)
                    list.remove(temp);
                else
                    break;
            }
    
            return list;
        }
    
        public static void main (String[] args) throws java.lang.Exception
        {
            String str = "abc";
            ArrayList<String> list = new ArrayList<>();
    
            list = strPerm(str,list);
            System.out.println("Total Permutations : "+list.size());
            for(int i=0;i<list.size();i++)
                System.out.println(list.get(i));
    
        }
    }
    

    http://ideone.com/nWPb3k