Permutation of String letters: How to remove repeated permutations?

前端 未结 10 2167
遇见更好的自我
遇见更好的自我 2020-12-25 08:39

Here is a standard function to print the permutations of characters of a string:

void permute(char *a, int i, int n)
{
   int j;
   if (i == n)
     printf(\         


        
相关标签:
10条回答
  • 2020-12-25 08:50

    Another approach could be:

    1. Presort the array.

    2. This will ensure that all duplicate are now consecutive.

    3. So, we just need to see the previous element which we we fixed (and permuted others)

    4. if current element is same as previous, don't permute.

    0 讨论(0)
  • 2020-12-25 08:53

    Take notes which chars you swapped previously:

     char was[256];
     /*
     for(j = 0; j <= 255; j++)
        was[j] = 0;
     */
     bzero(was, 256);
     for (j = i; j <= n; j++)
     {
        if (!was[*(a+j)]) {
          swap((a+i), (a+j));
          permute(a, i+1, n);
          swap((a+i), (a+j)); //backtrack
          was[*(a+j)] = 1;
        }
     }
    

    This has to be the fastest one from the entries so far, some benchmark on a "AAAABBBCCD" (100 loops):

    native C             - real    0m0.547s
    STL next_permutation - real    0m2.141s
    
    0 讨论(0)
  • 2020-12-25 08:55

    Algorithm steps:

    1. Store the given string into temporary string say "temp"
    2. Remove duplicates from temp string
    3. And finally call "void permute(char *a, int i, int n)" function to print all permutation of given string without duplicates

    I think, this is best and efficient solution.

    0 讨论(0)
  • 2020-12-25 09:00

    Standard library has what you need:

    #include <algorithm>
    #include <iostream>
    #include <ostream>
    #include <string>
    using namespace std;
    
    void print_all_permutations(const string& s)
    {
        string s1 = s;
        sort(s1.begin(), s1.end()); 
        do {
            cout << s1 << endl;
        } while (next_permutation(s1.begin(), s1.end()));
    }
    
    int main()
    {
        print_all_permutations("AAB");
    }
    

    Result:

    $ ./a.out
    AAB
    ABA
    BAA
    
    0 讨论(0)
  • 2020-12-25 09:03

    @Kumar, I think what you want is something like the following:

    #include <stdio.h>
    #include <string.h>
    
    /* print all unique permutations of some text. */
    void permute(int offset, int* offsets, const char* text, int text_size)
    {
        int i;
    
        if (offset < text_size) {
                char c;
                int j;
    
                /* iterate over all possible digit offsets. */
                for (i=0; i < text_size; i++) {
                        c=text[i];
                        /* ignore if an offset further left points to our
                           location or to the right, with an identical digit.
                           This avoids duplicates. */
                        for (j=0; j < offset; j++) {
                                if ((offsets[j] >= i) &&
                                    (text[offsets[j]] == c)) {
                                        break;
                                }
                        }
    
                        /* nothing found. */
                        if (j == offset) {
                                /* remember current offset. */
                                offsets[offset]=i;
                                /* permute remaining text. */
                                permute(offset+1, offsets, text, text_size);
                        }
                }
        } else {
                /* print current permutation. */
                for (i=0; i < text_size; i++) {
                        fputc(text[offsets[i]], stdout);
                }
                fputc('\n', stdout);
        }
    }
    
    int main(int argc, char* argv[])
    {
        int i, offsets[1024];
    
        /* print permutations of all arguments. */
        for (i=1; i < argc; i++) {
                permute(0, offsets, argv[i], strlen(argv[i]));
        }
    
        return 0;
    }
    

    This code is C, as requested, it's pretty fast and does what you want. Of course it contains a possible buffer overflow because the offset buffer has a fixed size, but this is just an example, right?

    EDIT: Did anyone try this out? Is there a simpler or faster solution? It's disappointing noone commented any further!

    0 讨论(0)
  • 2020-12-25 09:03

    Do not permute for same character at different position of the string.

    In Python:

    def unique_permutation(a, l, r):
        if l == r:
            print ''.join(a)
            return
        for i in range(l, r+1):
            if i != l and a[i] == a[l]:
                continue
            a[i], a[l] = a[l], a[i]
            unique_permutation(a, l+1, r)
            a[i], a[l] = a[l], a[i]
    
    0 讨论(0)
提交回复
热议问题