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(\
Another approach could be:
Presort the array.
This will ensure that all duplicate are now consecutive.
So, we just need to see the previous element which we we fixed (and permuted others)
if current element is same as previous, don't permute.
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
Algorithm steps:
I think, this is best and efficient solution.
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
@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!
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]