I want to print all permutation of string in lexicographic order. I wrote this code:
void permute(char *a, int i, int n) {
if (i == (n-1)) printf(\"\\\"%s
I am presuming you want a recursive version.
Here are two solutions.
Solution 1)
Since you want lexicographic, all you need to do is pick the next smallest possible when you need to pick. That's it!
For example, here is a recursive version in python
def permute(done, remaining):
if not remaining:
print done
return
sorted_rem = sorted(remaining)
l = len(sorted_rem)
for i in xrange(0, l):
c = sorted_rem[i]
# Move to c to done portion.
done.append(c)
remaining.remove(c)
# Permute the remaining
permute(done, remaining)
# Put c back.
remaining.append(c)
# Remove from done.
del done[-1]
permute([], [1,2,3,4])
That's it.
Solution 2)
While Solution 1 works and is easy to understand, I suspect we might be wasting some time by sorting. This solution is closer to what you have.
Recursion is basically mathematical induction in disguise, and that way of thinking is really useful in understanding how to write recursive programs.
For example, assume your permute method always constructs the permutations in lexicographic order.
Here is a recursive version, with that assumption, please read the comments to understand what is going on.
// By induction assumption, permute(a, i, n)
// goes through all the permutations of a[i], ..., a[n-1]
// in lexicographic order, by modifying a itself.
void permute(char *a, int i, int n) {
if (i == (n-1)) {
printf("%s\n", a);
return;
}
int j;
// We pick the n-i posibilities for the position a+i, then recursively
// compute the permutations of a[i+1], ..., a[n-1]
// So first pick the smallest possible for a+i, recurse.
// Then the next possible for a+i, then recurse etc.
for (j = i; j < n; j++) {
permute(a, i+1, n);
// By our induction assumption, at this point,
// a[i+1], a[i+2], .., a[n-1]
// must be the lexicographically the largest possible!
// So now reverse that portion.
reverse(a+i+1, a+n-1);
// Now we need to pick the lexicographically next element for
// position a+i. This is nothing but the element which is just
// larger than the current a+i.
int k = i+1;
while(k < n && a[i] > a[k]) {
k++;
}
if (k >= n) {
continue;
}
// Choose the next value for a+i.
swap(a+i, a+k);
}
// Notice that the portion a[i+1], ..., a[n-1] is sorted increasing.
// when the loop exits. Also a[i] will be the largest element.
// We need to reverse so that a[i], .., a[n-1] is the lexicographically
// largest permutation to maintain the induction (recursion) assumption.
reverse(a+i+1, a+n-1);
}
Notice the similarity between this, and the iterative version (specified by the others and section below), where you reverse a chunk at the end, and swap two elements.
btw, the common iterative algorithm for generating permutations in lexicographic order is Narayana Pandita's algorithm, mentioned by other, but not by name.
See this link: http://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order
This is what std::next of C++ and a host of other libraries use.
This algorithm even works when there are repeated elements, and can in fact be used to generate combinations! (Initialize your array with zeroes and ones).