Generate list of all possible permutations of a string

后端 未结 30 2545
故里飘歌
故里飘歌 2020-11-22 15:10

How would I go about generating a list of all possible permutations of a string between x and y characters in length, containing a variable list of characters.

Any l

相关标签:
30条回答
  • 2020-11-22 15:13

    You are going to get a lot of strings, that's for sure...

    \sum_{i=x}^y{\frac{r!}{{(r-i)}!}}
    Where x and y is how you define them and r is the number of characters we are selecting from --if I am understanding you correctly. You should definitely generate these as needed and not get sloppy and say, generate a powerset and then filter the length of strings.

    The following definitely isn't the best way to generate these, but it's an interesting aside, none-the-less.

    Knuth (volume 4, fascicle 2, 7.2.1.3) tells us that (s,t)-combination is equivalent to s+1 things taken t at a time with repetition -- an (s,t)-combination is notation used by Knuth that is equal to {t \choose {s+t}. We can figure this out by first generating each (s,t)-combination in binary form (so, of length (s+t)) and counting the number of 0's to the left of each 1.

    10001000011101 --> becomes the permutation: {0, 3, 4, 4, 4, 1}

    0 讨论(0)
  • 2020-11-22 15:13

    Non recursive solution according to Knuth, Python example:

    def nextPermutation(perm):
        k0 = None
        for i in range(len(perm)-1):
            if perm[i]<perm[i+1]:
                k0=i
        if k0 == None:
            return None
    
        l0 = k0+1
        for i in range(k0+1, len(perm)):
            if perm[k0] < perm[i]:
                l0 = i
    
        perm[k0], perm[l0] = perm[l0], perm[k0]
        perm[k0+1:] = reversed(perm[k0+1:])
        return perm
    
    perm=list("12345")
    while perm:
        print perm
        perm = nextPermutation(perm)
    
    0 讨论(0)
  • 2020-11-22 15:15

    You might look at "Efficiently Enumerating the Subsets of a Set", which describes an algorithm to do part of what you want - quickly generate all subsets of N characters from length x to y. It contains an implementation in C.

    For each subset, you'd still have to generate all the permutations. For instance if you wanted 3 characters from "abcde", this algorithm would give you "abc","abd", "abe"... but you'd have to permute each one to get "acb", "bac", "bca", etc.

    0 讨论(0)
  • 2020-11-22 15:15

    Recursive solution in C++

    int main (int argc, char * const argv[]) {
            string s = "sarp";
            bool used [4];
            permute(0, "", used, s);
    }
    
    void permute(int level, string permuted, bool used [], string &original) {
        int length = original.length();
    
        if(level == length) { // permutation complete, display
            cout << permuted << endl;
        } else {
            for(int i=0; i<length; i++) { // try to add an unused character
                if(!used[i]) {
                    used[i] = true;
                    permute(level+1, original[i] + permuted, used, original); // find the permutations starting with this string
                    used[i] = false;
                }
            }
    }
    
    0 讨论(0)
  • 2020-11-22 15:18

    There are a lot of good answers here. I also suggest a very simple recursive solution in C++.

    #include <string>
    #include <iostream>
    
    template<typename Consume>
    void permutations(std::string s, Consume consume, std::size_t start = 0) {
        if (start == s.length()) consume(s);
        for (std::size_t i = start; i < s.length(); i++) {
            std::swap(s[start], s[i]);
            permutations(s, consume, start + 1);
        }
    }
    
    int main(void) {
        std::string s = "abcd";
        permutations(s, [](std::string s) {
            std::cout << s << std::endl;
        });
    }
    

    Note: strings with repeated characters will not produce unique permutations.

    0 讨论(0)
  • 2020-11-22 15:18

    The following Java recursion prints all permutations of a given string:

    //call it as permut("",str);
    
    public void permut(String str1,String str2){
        if(str2.length() != 0){
            char ch = str2.charAt(0);
            for(int i = 0; i <= str1.length();i++)
                permut(str1.substring(0,i) + ch + str1.substring(i,str1.length()),
                         str2.substring(1,str2.length()));
        }else{
        System.out.println(str1);
        }
    }
    

    Following is the updated version of above "permut" method which makes n! (n factorial) less recursive calls compared to the above method

    //call it as permut("",str);
    
    public void permut(String str1,String str2){
       if(str2.length() > 1){
           char ch = str2.charAt(0);
           for(int i = 0; i <= str1.length();i++)
              permut(str1.substring(0,i) + ch + str1.substring(i,str1.length()),
                     str2.substring(1,str2.length()));
       }else{
        char ch = str2.charAt(0);
        for(int i = 0; i <= str1.length();i++)
            System.out.println(str1.substring(0,i) + ch +    str1.substring(i,str1.length()),
                     str2.substring(1,str2.length()));
       }
    }
    
    0 讨论(0)
提交回复
热议问题