我正在阅读尾部递归,如下所示
尾递归是指最后一行的递归调用。尾巴 可以通过将身体封闭在一起来机械地消除递归 while循环和用一个赋值替换递归调用 函数参数。
例如
void print(Iterator start, Iterator end, ostream& out=cout) {
if(start == end)
return;
out << *start++ << endl;
print(start, end, out);
}
按照上述规范转换为迭代
void print(Iterator start, Iterator end, ostream& out=cout) {
while(true) {
if(start == end)
return;
out << *start++ << endl;
}
}
在上面的段落中,提到“用每个函数参数替换一个赋值的递归调用,但在给定的例子中我们没有任何赋值?
任何人都可以解释并提供关于如何将递归转换为迭代函数的上述解释的示例吗?
答案 0 :(得分:7)
赋值隐藏在增量运算符中:
start++;
实际上是一项任务:
start = start+1;
实际上,这个例子(第一部分)并不是很好。
out << *start++ << endl;
print(start, end, out);
应该是
out << *start << endl;
print( start+1, end, out);
答案 1 :(得分:6)
我不认为,无论你指的是什么段落都很重要;只关注主要问题,你想将递归函数转换为正常的迭代函数,这可以(毫不费力地)完成,
void print(Iterator start, Iterator end, ostream& out=cout) {
while(start != end) {
out << *start++ << endl;
}
}
答案 2 :(得分:1)
它在C ++中隐藏了一点,但是start++
在循环中每次都分配一个新值。
答案 3 :(得分:1)
他们所说的是,你将tail函数调用的参数赋值给这个函数调用的参数变量,但是在这种情况下它不是必需的,因为你用相同的参数调用函数(因为像其他人说的那样,对第一个参数start
的更改发生在函数调用之前。)
实际上,如果精确地完成,迭代函数应该看起来像
void print(Iterator start, Iterator end, ostream& out=cout) {
while(true) {
if(start == end)
return;
out << *start++ << endl;
start = start;
end = end;
out = out;
}
}
但是这些作业完全是不必要的,即使在视觉上是正确的。
答案 4 :(得分:0)
递归到迭代的一般转换看起来像这样。
原始代码:
void print(Iterator start, Iterator end, ostream& out=cout) {
if(start == end)
return;
out << *start++ << endl;
print(start, end, out);
}
转换代码:
void print(Iterator start, Iterator end, ostream& out=cout) {
while(true) {
if(start == end)
return;
out << *start << endl;
// One assignment per function argument for 'general' tail recursion
start = start + 1; // (1)
end = end; // (2)
out = out; // (3)
}
}
包括解释中的三个作业。赋值(1)嵌入在start++
中,赋值(2)和(3)被优化掉。