我写了一个函数来计算整数的幂,然后取模数。我想知道我做的是尾递归:
int takeModulusTAILRECURSION(int coef, int x, int n, int module){
int result = 0;
if ( n > 0 )
result = takeModulusTAILRECURSION( mod(coef * x, module), x , n - 1, module );
else if ( n == 0)
result = mod ( coef , module );
return result;
}
//take modul of an integer ( both negative and positive )
int mod(int x, int modul){
while ( x < 0)
x += modul;
return x % modul;
}
这是另一个纯粹使用递归的函数,我认为它与上面不同:
int takeModulusNORMRECURSION(int x, int n, int module){
if ( n == 1 )
return mod( x, module );
else {
int total = x * takeModulusNORMRECURSION( x, n - 1, module);
return mod( total, module);
}
}
顺便说一句,在这些情况下,任何人都可以告诉我如何检查Eclipse中的帧堆栈?当我尝试(不知道对错)时,他们都运行了很多堆栈。
答案 0 :(得分:0)
这是否是尾递归取决于代码的编译方式。
当您直接将调用返回到另一个函数(可能是您自己)时,会发生尾递归。当编译器/解释器注意到这一点时,会发生尾调用优化(人们关心尾递归的原因),只是替换当前的堆栈帧而不是创建另一个堆栈帧。在你的情况下,如果它被天真地编译,你没有尾递归,因为你正在进行递归调用,然后将它分配给你的调用堆栈中的一个变量,稍后你将返回该变量。那个赋值步骤意味着你在调用另一个函数之后会做更多的事情,这会使你的代码不适合尾部调用优化。
然而一个好的编译器应该像这样重写你的代码:
int takeModulusTAILRECURSION(int coef, int x, int n, int module){
if ( n > 0 )
return takeModulusTAILRECURSION( mod(coef * x, module), x , n - 1, module );
else if ( n == 0)
return mod ( coef , module );
else
return 0;
}
//take modul of an integer ( both negative and positive )
int mod(int x, int modul){
while ( x < 0)
x += modul;
return x % modul;
}
现在它是尾递归的。
但是现在是否可能发生尾调用优化取决于语言和实现。例如,如果你的代码应该是Java,那么正如Does the JVM prevent tail call optimizations?指出的那样,无论你做什么,你都不会得到尾调用优化。
编辑:我说“tail recursive”表示“尾递归和尾调优化”。
答案 1 :(得分:0)
第一种方法是尾递归,因为当函数执行'return'时,它返回的值是一个不依赖于当时对另一个方法的调用的值。
第二种方法不是尾递归,事实上它不是递归的,因为它只是迭代x的值的变化。
第三个也是最后一个方法也是尾递归的,因为像第一个例子一样,当方法“返回”时,它能够在不调用任何方法的情况下这样做,包括它自己。
希望这有帮助。
答案 2 :(得分:0)