Could anybody help me turning this algorithm into an iterative one. I know that recursion is just iteration plus a stack but I did not manage to come up with a proper solution so far.
void rGenCombs(int n, int k, vector<int>& chosen, int idx,
vector<vector<int>>& combs) {
if (chosen.size() == k) {
combs.push_back(chosen);
return;
}
for (int i = idx; i <= n; ++i) {
chosen.push_back(i);
rGenCombs(n, k, chosen, i + 1, combs);
chosen.pop_back();
}
}
vector<vector<int>> genCombsRec(int n, int k) {
vector<vector<int>> combs;
vector<int> chosen;
rGenCombs(n, k, chosen, 1, combs);
return combs;
}
Update I have this right now. Problem is I cannot figure out which loops to write. Should be doable somehow with a simple while loop I guess.
vector<vector<int>> genCombs(int n, int k) {
vector<int> numStack, chosen;
vector<vector<int>> combs;
numStack.push_back(1);
while (!numStack.empty()) {
if (chosen.size() == k) {
combs.push_back(chosen);
chosen.pop_back();
continue;
}
chosen.push_back(numStack.back());
if (numStack.back() <= n) {
numStack.push_back(numStack.back() + 1);
} else {
numStack.pop_back();
}
}
return combs;
}
Solutions
For the different iterative algorithm without the need of a stack I ended up with the following:
int getNextIncIndex(const vector<int>& combs, int n) {
int k = static_cast<int>(combs.size());
for (int i = k - 1; i >= 0; --i) {
int distFromRight = k - i - 1;
if (combs[i] < n - distFromRight) {
return i;
}
}
return -1;
}
vector<vector<int>> genCombs(int n, int k) {
vector<vector<int>> combs;
vector<int> comb(k, 1);
iota(comb.begin(), comb.end(), 1);
while (true) {
for (int i = comb[k - 1]; i <= n ; ++i) {
comb[k - 1] = i;
combs.push_back(comb);
}
int incIdx = getNextIncIndex(comb, n);
if (incIdx == -1) {
break;
} else {
iota(comb.begin() + incIdx, comb.end(), comb[incIdx] + 1);
}
}
return combs;
}