Generating all permutations of a given string

前端 未结 30 1663
我寻月下人不归
我寻月下人不归 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:53

    String permutaions using Es6

    Using reduce() method

    const permutations = str => {
      if (str.length <= 2) 
      return str.length === 2 ? [str, str[1] + str[0]] : [str];
      
      return str
        .split('')
        .reduce(
          (acc, letter, index) =>
            acc.concat(permutations(str.slice(0, index) + str.slice(index + 1)).map(val => letter + val)),
          [] 
        );
    };
    
    console.log(permutations('STR'));

    0 讨论(0)
  • 2020-11-21 06:54

    python implementation

    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','')
    
    0 讨论(0)
  • 2020-11-21 06:54
    /*
         * 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);
                }
    
            }
    
        }
    
    0 讨论(0)
  • 2020-11-21 06:56

    All the previous contributors have done a great job explaining and providing the code. I thought I should share this approach too because it might help someone too. The solution is based on (heaps' algorithm )

    Couple of things:

    1. Notice the last item which is depicted in the excel is just for helping you better visualize the logic. So, the actual values in the last column would be 2,1,0 (if we were to run the code because we are dealing with arrays and arrays start with 0).

    2. The swapping algorithm happens based on even or odd values of current position. It's very self explanatory if you look at where the swap method is getting called.You can see what's going on.

    Here is what happens: 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);
                    }
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-21 06:56

    this worked for me..

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

    Of all the solutions given here and in other forums, I liked Mark Byers the most. That description actually made me think and code it myself. Too bad I cannot voteup his solution as I am newbie.
    Anyways here is my implementation of his description

    public class PermTest {
    
        public static void main(String[] args) throws Exception {
            String str = "abcdef";
            StringBuffer strBuf = new StringBuffer(str);
            doPerm(strBuf,0);
        }
    
        private static void doPerm(StringBuffer str, int index){
    
            if(index == str.length())
                System.out.println(str);            
            else { //recursively solve this by placing all other chars at current first pos
                doPerm(str, index+1);
                for (int i = index+1; i < str.length(); i++) {//start swapping all other chars with current first char
                    swap(str,index, i);
                    doPerm(str, index+1);
                    swap(str,i, index);//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);
        }
    }   
    

    I prefer this solution ahead of the first one in this thread because this solution uses StringBuffer. I wouldn't say my solution doesn't create any temporary string (it actually does in system.out.println where the toString() of StringBuffer is called). But I just feel this is better than the first solution where too many string literals are created. May be some performance guy out there can evalute this in terms of 'memory' (for 'time' it already lags due to that extra 'swap')

    0 讨论(0)
提交回复
热议问题