美文网首页我爱编程
JAVA 递归问题,kotlin 尾递归优化

JAVA 递归问题,kotlin 尾递归优化

作者: Artfox丶艺狸 | 来源:发表于2018-05-31 19:32 被阅读0次

递归(Recursive)是指自己方法内部调用自己

如求 1- n(n>1)之间的和:


    public static long sum(long n) {

        if (n == 1) {
            return 1;
        }

        return n + sum(n - 1);

    }

这是使用递归的方式求和,很消耗内存,比如我求 1 - 2147483647 ( Integer.MAX_VALUE ) ,就会StackOverflowError ,堆栈溢出

StackOverflowError

但是其实使用循环是可以计算出的

    static long sum(long n){
        
        long res = 0;
        while (n > 0){
            res+=n;
            n--;
        }
        
        return res;
    }

继续求 1 - 2147483647 ( Integer.MAX_VALUE ) 的和

结果

第二行是结果,第三行是用时

那么什么是尾递归呢?

就是递归时只返回函数本身,没有其他计算
即:

    static long sum(long n,long sum){
        
        if (n == 0){
            return sum;
        }
        return sum(n - 1,n+sum);
    }

在某些语言中,写成这样的递归在编译时会被自动优化,或者运行时会清除上次的栈信息,因为上次执行中的任何数据在下次执行时都是无关的

那么在 java上既然可能会出现问题,那么在使用递归时需要注意,尽量使用循环,或者在计算很小的数据时使用

在kotlin中,我们写成尾递归的时候,配合关键字 tailrec

如下:

tailrec fun sum(n: Int, res: Long): Long {
    if (n == 0) {
        return res;
    }
    return sum(n - 1, res + n)
}

测试代码

fun main(args: Array<String>) {

    val start = System.currentTimeMillis()
    val result = sum(Int.MAX_VALUE, 0)
    val end = System.currentTimeMillis()

    println(result)
    println("time:${end - start}")

}
kotlin结果

结果和上面使用循环的结果一致
时间上好像变短了。。。

反编译kotlin生成的class文件

kotlin生成的class

现在测试不加 tailrec 试试

StackOverflowError

一样会溢出
再次反编译class查看


kotlin class

代码并没有做优化
因此在使用 kotlin 时,可以使用关键字 tailrec 来进行优化尾递归
注意:必须是尾递归!!!

而使用 java编写时,尽量避免使用递归做深度的计算,可以使用循环代替!

相关文章

  • JAVA 递归问题,kotlin 尾递归优化

    递归(Recursive)是指自己方法内部调用自己 如求 1- n(n>1)之间的和: 这是使用递归的方式求和,很...

  • 7.尾递归优化

    尾递归:最后一行调用自身之后没有任何操作直接返回kotlin尾递归优化,关键字tailrec如: 不优化的话大量的...

  • Kotlin语言(九):特性

    1、尾递归优化 尾递归:函数在调用自己之后没有再执行其他任何操作就是尾递归 尾递归优化的原理就是将递归转换成迭代,...

  • kotlin精讲-第2章(11)kotlin函数加强_下

    Kotlin相比于Java 目标 尾递归函数 我们首先说递归函数,什么是递归函数呢?递归函数指的的在方法体内部还去...

  • 什么是尾调用?什么是尾递归?尾调用的优化?尾递归优化?

    尾调用优化 尾递归(尾调用优化)

  • 第2模块第1章2829递归的作用尾递归优化

    尾递归优化 def cal(n): print(n) return cal(n+1) cal(1) 尾递归优化并不...

  • 9. 递归函数

    使用递归函数需要注意防止栈溢出解决递归调用栈溢出的方法是通过尾递归优化遗憾的是,大多数编程语言没有针对尾递归做优化...

  • 尾递归优化

    “尾递归优化”的含义是:如果递归函数属于尾递归,那么运行时会优化其调用过程。优化主要针对调用栈,将多层调用,转化为...

  • 2018-07-28

    递归函数以及尾递归优化: #利用递归函数计算阶乘 ... #N! = 1 * 2 * 3 * 4 * ... * ...

  • 递归调用优化

    尾递归优化 函数调用自身,称为递归。如果尾调用自身,就称为尾递归。 递归非常耗费内存,因为需要同时保存成千上百个调...

网友评论

    本文标题:JAVA 递归问题,kotlin 尾递归优化

    本文链接:https://www.haomeiwen.com/subject/bxnqsftx.html