Scala 中的尾递归阶乘函数
Tail Recursive Factorial Function in Scala
我认为下面的阶乘函数是尾递归的,当我测试它时,它在 10 之前工作正常,在 20(负输出)时变得奇怪,当我插入 100 时,答案是 0:
def factorial(n: Int, m: Int = 1): Int =
if (n == 0) m else fact(n-1, m * n)
但是当我把 @tailrec 放在上面时,我得到以下错误:
error: not found: type tailrec
我不明白为什么这个函数不是尾递归的。堆栈递归阶乘函数是:
def factorial(n: Int): Int =
if (n == 0) 1 else n * factorial(n-1)
上述函数在每次递归调用时修改外部表达式after else。而第一个函数只修改函数内部的内容。现在,为了制作递归阶乘函数,他们所做的是在函数内部创建一个函数。但是,递归阶乘函数可以只用这个问题中第一个函数的主体来创建吗?
另外,前一个函数中的"m"是变量吗?
编辑:现在按照 中的建议进行操作后,
如果函数不是尾递归的,我会收到错误消息:
error: could not optimize @tailrec annotated method factorial: it contains a recursive call not in tail position
几件事:
您必须导入 @tailrec
注释才能在没有全名的情况下使用它:
import scala.annotation.tailrec
@tailrec
def factorial(n: Int, m: Int = 1): Int =
if (n == 0) m else fact(n-1, m * n)
没有 @tailrec
scalac
仍然可以进行尾递归优化,只是不会强制执行它(如果 TRO 不可能,编译也不会失败)。
整数的容量有限 - 它是 32 位的2-compliment,所有大于 2^31-1 的东西都会溢出并变成负数
所以你必须导入注释或使用全名 (@scala.annotation.tailrec
) 并用更大的东西替换 Int
(Long
也不够,更像是 BigInteger
).
我认为下面的阶乘函数是尾递归的,当我测试它时,它在 10 之前工作正常,在 20(负输出)时变得奇怪,当我插入 100 时,答案是 0:
def factorial(n: Int, m: Int = 1): Int =
if (n == 0) m else fact(n-1, m * n)
但是当我把 @tailrec 放在上面时,我得到以下错误:
error: not found: type tailrec
我不明白为什么这个函数不是尾递归的。堆栈递归阶乘函数是:
def factorial(n: Int): Int =
if (n == 0) 1 else n * factorial(n-1)
上述函数在每次递归调用时修改外部表达式after else。而第一个函数只修改函数内部的内容。现在,为了制作递归阶乘函数,他们所做的是在函数内部创建一个函数。但是,递归阶乘函数可以只用这个问题中第一个函数的主体来创建吗?
另外,前一个函数中的"m"是变量吗?
编辑:现在按照
error: could not optimize @tailrec annotated method factorial: it contains a recursive call not in tail position
几件事:
您必须导入
@tailrec
注释才能在没有全名的情况下使用它:import scala.annotation.tailrec @tailrec def factorial(n: Int, m: Int = 1): Int = if (n == 0) m else fact(n-1, m * n)
没有
@tailrec
scalac
仍然可以进行尾递归优化,只是不会强制执行它(如果 TRO 不可能,编译也不会失败)。整数的容量有限 - 它是 32 位的2-compliment,所有大于 2^31-1 的东西都会溢出并变成负数
所以你必须导入注释或使用全名 (@scala.annotation.tailrec
) 并用更大的东西替换 Int
(Long
也不够,更像是 BigInteger
).