C++ 使用尾部递归实现Tak函数
是否有可能实施以下措施: 以某种方式在C/C++中递归尾部,以便gcc/g++能够执行尾部递归优化?C++ 使用尾部递归实现Tak函数,c++,c,compiler-optimization,tail-recursion,C++,C,Compiler Optimization,Tail Recursion,是否有可能实施以下措施: 以某种方式在C/C++中递归尾部,以便gcc/g++能够执行尾部递归优化? 我不确定嵌套递归函数调用是否会混淆编译器。C++中的 尾递归优化要求只有1个递归调用(基本上允许它转换成循环),递归调用是函数中的最后一个操作: 例如: unsigned int f( unsigned int a ) { if ( a == 0 ) { return a; } return f( a - 1 ); // tail recursion
我不确定嵌套递归函数调用是否会混淆编译器。C++中的 尾递归优化要求只有1个递归调用(基本上允许它转换成循环),递归调用是函数中的最后一个操作: 例如:
unsigned int f( unsigned int a )
{
if ( a == 0 )
{
return a;
}
return f( a - 1 ); // tail recursion
}
由于Tak函数在每次“迭代”中需要4个递归调用:
如您所见,最后一个调用是递归的,但它内部有3个递归调用。这防止了尾部递归优化(并且没有逻辑方法将其转换为非递归循环-这是获得尾部递归优化所必需的)
另一种实现方法是:
int tak(int x, int y, int z)
{
while (x > y)
{
int oldx = x, oldy = y;
x = tak(x - 1, y, z);
y = tak(y - 1, z, oldx);
if (x <= y)
break;
z = tak(z - 1, oldx, oldy);
}
return z;
}
inttak(intx,inty,intz)
{
while(x>y)
{
int oldx=x,oldy=y;
x=tak(x-1,y,z);
y=tak(y-1,z,oldx);
如果(x直接从你的数学定义出发,我们可以将函数写成:
int tak(int x, int y, int z){
if(x>y)
return tak(tak(1-x,y,z), tak(y-1,z,x), tak(z-1,x,y));
else
return z;
}
但是,您不能使用尾部重新融合,因为它不能转换为循环。因为有多个重新融合调用。我不这么认为?因为它只会开始执行所有操作,并保持分支?编译器是否可以将直接实现转换为循环实现?@jh314什么是循环“直接实现”?语句返回tak(tak(x-1,y,z),tak(y-1,z,x),tak(z-1,x,y));
可能吗?呃。它不太可能看到这一点并将其转换为循环版本。循环为您带来的唯一好处是少一些函数调用(意味着调用堆栈不会被淹没太多)。递归调用的数量不是重要的变量。有些函数的一个递归调用不能转换为循环,有些函数的许多递归调用都可以。重要的是调用的位置。谢谢@Jules。非常感谢!
int tak(int x, int y, int z){
if(x>y)
return tak(tak(1-x,y,z), tak(y-1,z,x), tak(z-1,x,y));
else
return z;
}