I tried to solve the simple problem of generating all permutations of length n with m distinct elements where repetition is allowed. Doing this recursively took me like 10 minutes:
void genAllPermsRec(vector<int>& perm, vector<vector<int>>& perms, int n, int m) {
if (perm.size() == n) {
perms.push_back(perm);
return;
}
for (int i = 0; i < m + 1; ++i) {
perm.push_back(i);
genAllPermsRec(perm, perms, n, m);
perm.pop_back();
}
}
I tried to do it iteratively then and it took me a lot longer. I ended up looking exactly at what happens in the recursive version and came up with the following solution:
vector<vector<int>> genAllPerms(int n, int m) {
vector<vector<int>> perms;
vector<int> perm(1, 0);
int i = 0;
while (!perm.empty()) {
if (perm.size() == n) {
perms.push_back(perm);
if (perm.back() < m) {
perm.pop_back();
++i;
continue; // That is why Python has the while: .. else: construct.
}
while (perm.back() == m) { perm.pop_back(); }
if (!perm.empty()) {
perm.back() += 1;
i = 0;
}
} else { perm.push_back(i); }
}
return perms;
}
It seems to work but I am not satisfied with the result. I suspect that there is a more intuitive way to approach the problem that would lead to shorter code. Please enlighten me :)
for (int i = 0; i < m + 1; ...iterates fromi==0up toi==m. Either start withi=1or proceed whilei < m. \$\endgroup\$m, so it finds permutations of \$m+1\$ values, not \$m\$. \$\endgroup\$