什么是python尾递归

技术什么是python尾递归本篇内容主要讲解“什么是python尾递归”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“什么是python尾递归”吧!递归是啥?递归函数大家肯定写

本文主要讲解“什么是python尾部递归”。感兴趣的朋友不妨看看。本文介绍的方法简单、快速、实用。让边肖带你学习什么是python尾部递归。

递归是啥?

递归函数肯定是大家写的。估计学校第一个例子就是斐波那契数列。例如:

intFibonacci(n){ if(N2)return n;返回斐波那契(n-1)斐波那契(n-2);}递归函数只是在函数中递归调用自身。编写递归函数时,需要注意递归函数的结束条件。递归函数确实可以简化很多算法的实现,比如常见的二叉树遍历。但是在编写递归函数时,最常见的问题是所谓的“堆栈溢出”。

为什么会出现“栈溢出”?因为在函数调用过程中,应该使用存储结构“栈”来保存运行时的一些状态,比如函数调用过程中变量的拷贝,函数调用的地址等等。但是“stack”的存储空间往往是有限的,当超过其存储空间时,就会抛出著名的异常/错误“StackOverflowError”。

让我们以一个简单的加法为例,例如:

int sum(intn){ if(n=1)returnn;返回和(n-1);} STD : cout sum(100)STD : endl;STD : cout sum(1000000)STD : endl;简而言之,编译运行后,对于较小的数字可以得到正确的答案,当数字放大时,会直接出现“分段故障”。

尾递归又是啥?

我最初了解这个概念是因为很多年前的一次面试,面试官问我:“你知道什么是尾部递归吗?”我以为是“伪”递归。是假递归吗?刚开始的时候,我也是处于懵懵懂懂的状态(刚开始的时候,面试官忍住没笑太多)。从“尾”字可以看出,如果函数在尾部递归调用自己。上面的例子被写成尾部递归,如下所示:

inttailsum(intn,int sum){ if(n==0)return sum;returntailsum(n-1,sum n);}可以试试结果,计算从1增加到1000000,还是分段故障。为什么呢?因为这种编写方式,本质上还是有很多层嵌套的函数调用,中间还是有推和弹出的,占用存储空间(只是比之前的方法能节省一些空间)。

尾递归优化

当您优化编译选项时,是时候见证奇迹并计算正确的结果了。如图所示:

什么是python尾递归

默认为c分段故障,启动编译优化后可以正常计算结果。

原因是编译器有助于做尾部递归优化,所以可以打开汇编代码看一看(这里没有显示C的)。稍后我将使用熟悉的基于JVM的语言Scala来解释这个优化过程。(看来Java的编译器在这方面还没有优化,至少我本地的JDK8没有,不知道有没有最新版本。)(scala本身提供了一个注释,帮助编译器强制检查是否可以执行尾部递归优化@tailrec)。

objectTailRecObject { deftailSum(n : int,sum : int): int={ if(n==0)returnsum;returntailsumn(n-1,n sum);} defmain(args 3360 array[string]){ println(tail sum(100,0)) println (tailsum (100000,0))}}结果如下图所示。默认情况下,scalac做了尾部递归优化,可以正确计算结果。当通过-g:notailcalls编译参数移除尾部递归优化时,线程“main”Java . lang . stack溢出错误发生。

什么是python尾递归

默认情况下,启用尾部递归来优化正常计算结果,禁用尾部递归优化时,选择“StackOverflow”。

让我们看看生成的字节码有什么不同。

什么是python尾递归

包含通过尾部递归优化的字节码,直接转到循环。

什么是python尾递归

禁用尾部递归优化的字节码,方法调用。

从上面可以看出,尾部递归优化后,变成了一个循环(前面的C也类似)。

至此,相信大家对“什么是python尾递归”有了更深的理解,让我们在实践中去做吧!这是网站。更多相关内容,可以进入相关渠道查询,关注我们,继续学习!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/65484.html

(0)

相关推荐

  • JavaScript中字符串对象有哪些方法

    技术JavaScript中字符串对象有哪些方法这篇文章主要介绍JavaScript中字符串对象有哪些方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! JavaScri

    攻略 2021年12月8日
  • Spark Connector Reader 原理与实践是怎样的

    技术Spark Connector Reader 原理与实践是怎样的本篇文章为大家展示了Spark Connector Reader 原理与实践是怎样的,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介

    攻略 2021年12月3日
  • 常见Redis面试题有哪些

    技术常见Redis面试题有哪些本篇内容主要讲解“常见Redis面试题有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“常见Redis面试题有哪些”吧!1、Redis支持的数

    攻略 2021年11月12日
  • MySQL数据分析怎么解决

    技术MySQL数据分析怎么解决本篇内容主要讲解“MySQL数据分析怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MySQL数据分析怎么解决”吧!作为最为流行的开源数据

    攻略 2021年12月3日
  • 澳大利亚旅游得多少钱,去澳大利亚旅游要花多少钱

    技术澳大利亚旅游得多少钱,去澳大利亚旅游要花多少钱我想你悉尼和墨尔本这两个最著名的城市肯定是要去的吧。如果是穷游,可以在城内不采用交通工具,完全靠走。吃和住弹性都比较大,自己选择适合自己价位的酒店就行,如果不介意的话去超

    生活 2021年10月25日
  • 如何理解Go错误处理之用panic取代rr != nil的模式

    技术如何理解Go错误处理之用panic取代rr != nil的模式这篇文章主要介绍“如何理解Go错误处理之用panic取代rr != nil的模式”,在日常操作中,相信很多人在如何理解Go错误处理之用panic取代rr

    攻略 2021年10月21日