I want to share a better version of permutation with you.
Yesterday, when I was reading Horowitz's Fundamentals of Data Structures In C++, and I noticed that the result of the code, at page 32, in the book is not what I want.
For example, if I have an array of {'a', 'b', 'c'}, then the result it provides is:
abc
acb
bac
bca
cba
cab
Notice that the last two cases don't fit what I want: when 'c' is fixed, all the other letters at its right should start from a, with relative order, \$a \lt b \lt c \lt \ldots \lt z\$, so the result should be:
...
cab
cba
Here is my code, which corrects the order with two modified swaps:
#include <iostream>
using namespace std;
void printPermutation(char *a, const int k, const int m);
void swap2(char *a, const int l, const int r);
void swap3(char *a, const int l, const int r);
int main() {
char str[] = {'a', 'b', 'c', 'd', 'e'};
printPermutation(&str[0], 0, sizeof(str)-1);
return 0;
}
void printPermutation(char *a, const int k, const int m) {
if (k == m) {
for (int i = 0; i <= m; i++) {
cout << a[i];
}
cout << endl;
}
else {
for (int i = k; i <= m; i++) {
// the code in the book just use swap, but I change them.
swap2(a, k, i); // here
printPermutation(a, k+1, m);
swap3(a, k, i); // and here
}
}
}
// swap2 will move the element at index r to l,
// by continuously swap with element at its left
void swap2(char *a, const int l, const int r) {
for (int i = r; l < i; i--) {
swap(a[i], a[i-1]);
}
}
// The same concept with swap2, but from left to right
void swap3(char *a, const int l, const int r) {
for (int i = l; i < r; i++) {
swap(a[i], a[i+1]);
}
}
How can I further simplify the code?
I like the idea that the author used recursion to make things beautifully simple. But to achieve the result I want as described above, I have to add two additional, a little bit similar, functions.
printPermutation
will print the range $$[k, m]$$, not $$[k, m)$$, sorry if this make you confused... \$\endgroup\$