Your approach works (with the correct condition as provided by greedybuddha), but can be achieved much simpler (as suggested by chris).
#include <algorithm>
#include <iostream>
#include <string>
int main()
{
std::string s("abcdefg");
do
{
std::cout << s << "\n";
}
while ( std::next_permutation(s.begin(), s.end()) );
}
Well what does it do? std::next_permutation
takes two iterators, one is the beginning of your string, the second is the end, so basically you're saying "consider the whole string". It permutes the string s
such that after the call, s
contains the unique permutation that would appear in lexicographical order directly after the previous value of s
. If s
is the last such permutation (i.e. "gfedcba" for input "abcdefg"), std::next_permutation
returns false
and thus you know you're done.
Since you're not creating any new (temporary) strings with this code, it is not only more readable, but also faster. On my machine, your algorithm takes roughly 5 seconds for "abcdefghij", the one using std::next_permutation
finishes in less than a second. With another character it becomes worse to 54sec vs. 6.8sec.
Note that if the initial string isn't sorted, this will not give the complete list of permutations. But of course there is an easy solution for this: Perform std::sort(s.begin(), s.end());
before permuting.