📜  Scala中的尾递归

📅  最后修改于: 2022-05-13 01:55:47.745000             🧑  作者: Mango

Scala中的尾递归

递归是一种将问题分解为较小的子问题并针对每个问题调用自身的方法。也就是说,它只是意味着函数调用自身。尾递归函数比非尾递归函数更好,因为尾递归可以通过编译器进行优化。如果递归调用是函数完成的最后一件事,则称递归函数为尾递归。无需记录之前的状态。

对于尾递归函数,程序中将使用包import scala.annotation.tailrec

句法:

@tailrec
def FuntionName(Parameter1, Parameter2, ...): type = …

让我们通过例子来理解尾递归。

例子 :

// Scala program of GCD using recursion 
import scala.annotation.tailrec
  
// Creating object 
object GFG 
{ 
    // Function defined 
    def GCD(n: Int, m: Int): Int =
    {
        // tail recursion function defined 
        @tailrec def gcd(x:Int, y:Int): Int=
        { 
            if (y == 0) x 
            else gcd(y, x % y) 
        } 
        gcd(n, m)
    } 
      
    // Main method 
    def main(args:Array[String]) 
    { 
        println(GCD(12, 18)) 
    } 
} 

输出:

6

正如我们在上面的示例中看到的, @tailrec用于 gcd函数,即尾递归函数。通过使用尾递归,无需记录 gcd函数的先前状态。

例子 :

// Scala program of factorial using tail recursion 
import scala.annotation.tailrec 
    
// Creating object 
object GFG 
{ 
    // Function defined 
    def factorial(n: Int): Int =
    { 
        // Using tail recursion 
        @tailrec def factorialAcc(acc: Int, n: Int): Int =
        { 
            if (n <= 1) 
                acc 
            else 
                factorialAcc(n * acc, n - 1) 
        } 
        factorialAcc(1, n) 
    } 
        
    // Main method 
    def main(args:Array[String]) 
    { 
        println(factorial(5)) 
    } 
} 

输出:

120

在上面的代码中,我们可以使用@tailrec注解来确认我们的算法是尾递归的。

如果我们使用这个注解并且我们的算法不是尾递归的,编译器就会报错。例如,如果我们尝试在上面的阶乘方法示例中使用此注解,我们将得到以下编译时错误。

例子 :

// Scala program of factorial with tail recursion 
import scala.annotation.tailrec 
    
// Creating object 
object GFG 
{ 
    // Function defined 
    @tailrec def factorial(n: Int): Int =
    { 
        if (n == 1) 
            1
        else 
            n * factorial(n - 1) 
    } 
        
    // Main method 
    def main(args:Array[String]) 
    { 
        println(factorial(5)) 
    } 
} 

输出: