Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permutation of String letters: How to remove repeated permutations?

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("%s\n", a);
   else
   {
        for (j = i; j < n; j++) //check till end of string
       {
          swap((a+i), (a+j));
          permute(a, i+1, n);
          swap((a+i), (a+j)); //backtrack
       }
   }
} 

void swap (char *x, char *y)
{
    char temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

It works fine but there is a problem, it also prints some duplicate permutations, exapmle:

if string is "AAB"

the output is:

AAB
ABA
AAB
ABA
BAA
BAA

This is having 3 duplicate entries as well.

Can there be a way to prevent this to happen?

--

Thanks

Alok Kr.

like image 942
Kumar Alok Avatar asked Aug 02 '11 19:08

Kumar Alok


People also ask

How do you remove Reputition from permutations?

There is a subset of permutations that takes into account that there are double objects or repetitions in a permutation problem. In general, repetitions are taken care of by dividing the permutation by the factorial of the number of objects that are identical.

How will you print all permutations of characters in a string?

Using a backtracking approach, all the permutations of the given string can be printed. Backtracking is an algorithm for finding all the possible solutions by exploring all possible ways.

How do you find the number of permutations of a string?

The number of permutations of n objects taken r at a time is determined by the following formula: P(n,r)=n! (n−r)!


2 Answers

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
like image 84
Karoly Horvath Avatar answered Sep 22 '22 23:09

Karoly Horvath


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
like image 28
fizzer Avatar answered Sep 24 '22 23:09

fizzer