Generating all permutations of a given string

前端 未结 30 1662
我寻月下人不归
我寻月下人不归 2020-11-21 06:35

What is an elegant way to find all the permutations of a string. E.g. permutation for ba, would be ba and ab, but what about longer st

相关标签:
30条回答
  • 2020-11-21 06:43

    Permutation of String:

    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));
        }   
    }
    
    0 讨论(0)
  • 2020-11-21 06:44

    Let me try to tackle this problem with 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) }
        }
    }
    

    Core concept: Break down long list into smaller list + recursion

    Long answer with example list [1, 2, 3, 4]:

    Even for a list of 4 it already kinda get's confusing trying to list all the possible permutations in your head, and what we need to do is exactly to avoid that. It is easy for us to understand how to make all permutations of list of size 0, 1, and 2, so all we need to do is break them down to any of those sizes and combine them back up correctly. Imagine a jackpot machine: this algorithm will start spinning from the right to the left, and write down

    1. return empty/list of 1 when list size is 0 or 1
    2. handle when list size is 2 (e.g. [3, 4]), and generate the 2 permutations ([3, 4] & [4, 3])
    3. For each item, mark that as the last in the last, and find all the permutations for the rest of the item in the list. (e.g. put [4] on the table, and throw [1, 2, 3] into permutation again)
    4. Now with all permutation it's children, put itself back to the end of the list (e.g.: [1, 2, 3][,4], [1, 3, 2][,4], [2, 3, 1][, 4], ...)
    0 讨论(0)
  • 2020-11-21 06:44

    Java implementation without recursion

    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;
    }
    
    0 讨论(0)
  • 2020-11-21 06:44
    //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--]);
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-21 06:45

    //insert each character into an arraylist

    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) + "  ");
        }
    }
    
    0 讨论(0)
  • 2020-11-21 06:46

    One of the simple solution could be just keep swapping the characters recursively using two pointers.

    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;
        }
    }
    }
    
    0 讨论(0)
提交回复
热议问题