Original Post
I have the following function: I want to write an iterative version that simulates the recursion in that function. After reading through some stuff and trying to visualize how the compiler does this, I came up with this: This seems to work, but I think that I'm performing some redundant operations and that there's a simpler way to do this. The reason is that the iterative version is much slower than the recursive one. I counted the number of recursive calls in the first function and the number of loop iterations in the second function, and the latter is always much larger than the former, but shouldn't they be the same? How can I improve this implementation? Thanks in advance.
int binomial(int n, int k) {
if (n < k)
return 0;
if (k == 0)
return 1;
int result1 = binomial(n-1, k);
int result2 = binomial(n-1, k-1);
return result1 + result2;
}
const int GARBAGE = -999999;
enum Location {
START,
AFTER_FIRST,
AFTER_SECOND,
};
struct StackFrame {
int n, k;
int result1, result2;
Location returnAddress;
StackFrame(int nn, int kk, Location ra, int res1 = GARBAGE, int res2 = GARBAGE)
:n(nn), k(kk), returnAddress(ra), result1(res1), result2(res2) {}
};
int binomialIter(int an, int ak) {
stack<StackFrame> stk;
stk.push(StackFrame(an, ak, AFTER_SECOND));
Location currLine = START;
int returnValue = GARBAGE;
while (!stk.empty()) {
switch (currLine) {
case START: {
StackFrame &curr = stk.top();
if (curr.n < curr.k) {
returnValue = 0;
currLine = curr.returnAddress;
stk.pop();
} else if (curr.k == 0) {
returnValue = 1;
currLine = curr.returnAddress;
stk.pop();
} else {
stk.push(StackFrame(curr.n-1, curr.k, AFTER_FIRST));
currLine = START;
}
break;
}
case AFTER_FIRST: {
StackFrame &curr = stk.top();
curr.result1 = returnValue;
stk.push(StackFrame(curr.n-1, curr.k-1, AFTER_SECOND, curr.result1));
currLine = START;
break;
}
case AFTER_SECOND: {
StackFrame &curr = stk.top();
curr.result2 = returnValue;
returnValue = curr.result1 + curr.result2;
currLine = curr.returnAddress;
stk.pop();
break;
}
}
}
return returnValue;
}