A beautiful and easy way of permutation with recursion 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 &lt;iostream&gt;
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(&amp;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 &lt;= m; i++) {
            cout &lt;&lt; a[i];
        }
        cout &lt;&lt; endl;
    }
    else {
        for (int i = k; i &lt;= 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 &lt; 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 &lt; 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.
The simpler code would look something like this:

#include &lt;string&gt;
#include &lt;algorithm&gt;
#include &lt;iostream&gt;

int main() {
    std::string s = "abcde";

    while (std::next_permutation(s.begin(), s.end()))
        std::cout &lt;&lt; s &lt;&lt; "\n";
}


If you wanted to do something on the same general order as a Python generator, you'd use C++'s new coroutine support. What's currently included is (by intent) very low-level, so you need a fair amount of infrastructure on top of it before it's easy to write a Python-like generator.

To keep from getting buried in details you probably don't care a lot about (right now) I'll use Kenny Kerr's Generator class (the first 173 lines, transplanted into a header). Using it, we get something like this:

#include "generator.hpp"
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;algorithm&gt;

template &lt;class T&gt;
generator&lt;T&gt; perm(T initial) {
    while (std::next_permutation(initial.begin(), initial.end()))
        co_yield initial;
}

int main() { 
    using namespace std::literals;
    for (auto const &amp;i : perm("abcde"s))
        std::cout &lt;&lt; i &lt;&lt; "\n";
}


As to your code, a few points jump out:


Don't use std::endl. It flushes the stream, which you almost never want. Just use '\n'. On the rare occasion that you do want to flush the stream, use std::flush.
The C library reserves most names that start with str, so it's probably better to avoid using that as a name.
using namespace std; is widely considered a problem except under a small number of rather unusual circumstances.
If you really want to do this (more) on your own, you might want to take a look at std::rotate, which can replace both your swap2 and swap3. std::rotate will also typically be more efficient than your implementation.
swap2 and swap3 strike me as poor names. At first glance, it seems like rotate_left and rotate_right would probably be better names (but also see above).