尾递归(Tail Recursion)和Continuation】的更多相关文章

递归: 就是函数调用自己. func() { foo(); func(); bar(); } 尾调用:就是在函数的最后,调用函数(包括自己). foo(){ return bar(); } 尾递归:就是在函数的最后,调用自身. func() { foo(); return func(); } 尾递归是递归的优化,优化的目的是栈深度=1,永不StackOverflow.所有的递归都能转成尾递归.简单的场景,比如计算阶乘N!和Fibonacci数列,可以用parameter代替临时变量,实现尾递归.…
定义[个人理解]: 尾递归,即是将外层得出的常量计算因子,以函数参数的形式逐层向内传递,即内层调用整合外层调用的产出,整个递归的结果最终由最内层的一次函数调用得出:而通常的递归则是外层调用阻塞.等待内层调用的产出,最后由最上层的一次函数调用得出最终结果. 优执: 适度应用,可以带来效率的提升,同时在一定程度上提升程序的稳定性. 局限: 效率提升取决于编译器的优化策略,最终结果存在不确定性,即使内层调用在逻辑上已可独立运行: 仅可作为潜在的效率提升措施,但不能做为循环的替代,因为其不能保证 100…
Scala对尾递归进行了优化,甚至提供了专门的标注告诉编译器需要进行尾递归优化.不过这种优化仅限于严格的尾递归,间接递归等情况,不会被优化. 尾递归的概念 递归,大家都不陌生,一个函数直接或间接的调用它自己,就是递归了.我们来看一个简单的,计算阶乘的例子. def factorial(n: Int): Int = { if( n <= 1 ) 1 else n * factorial(n-1) } 以上factorial方法,在n>1时,需要调用它自身,这是一个典型的递归调用.如果n=5,那么…
尾递归 - Tail Recursion尾递归是针对传统的递归算法而言的, 传统的递归算法在很多时候被视为洪水猛兽. 它的名声狼籍, 好像永远和低效联系在一起.尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量. 直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去.以n!为例介绍,后面例子n=5. 代码线性递归 int Rescuvie(int n) { ) ? : n * Rescu…
递归函数应用 首先,我们来对比两个递归方法的求值步骤. 假设有方法gcd,用来计算两个数的最大公约数.下面是欧几里得算法的实现: def gcp(a: Int, b: Int): Int = if (b == 0) a else gcp(b, a % b) gcp(14, 21)的求解过程如下: gcp(14, 21) if (21 == 0) 14 else gcd(21, 14 % 21) if (false) 14 else gcd(21, 14 % 21) gcd(21, 14 % 21…
cps全称叫continuation passing style,简要来讲就是告诉函数下一步做什么的递归方式,由于普通递归有栈溢出的问题,而cps都是尾递归(tail recursion),尾递归则是没有栈溢出问题的,所以haskell推荐都用cps的方式去编写代码. 当然,相对于普通递归方式,cps也有着非常不便于理解的问题. def fact(n): if (n==0): return 1 else: return n* fact(n-1) print fact(400) 这是一段递归求阶乘…
接着昨天的文章,再示范一个稍微复杂一点的尾递归tail recursion例子:计算第n个Fibonacci数.Fibonacci数第一.第二个数值分别是0,1,按顺序后面的数值是前面两个数的加合.例如:0,1,1,2,3,5... def fib(n: Int): Int = { @annotation.tailrec def go(cnt: Int, prev: Int, cur: Int): Int = cnt match { case m if (m < 0 ) => sys.erro…
Clojure首先是FP, 但是由于基于JVM, 所以不得已需要做出一些妥协, 包含一些OO的编程方式 Scala首先是OO, Java语法过于冗余, 一种比较平庸的语言, Scala首先做的是简化, 以更为简洁的方式来编写OO, 主要利用'type inference'能推断出来的, 你就不用写, 但如果仅仅这样, 不如用python 所以Scala象其名字一样, "可伸展的语言", 它是个大的集市, 它积极吸纳其他语言的优秀的特征, 最重要的就是FP, 你可以使用Scala来写OO…
Continuation Pass Style在函数式编程(FP)中有一种被称为Continuation Passing Style(CPS)的风格.在这种风格的背后所蕴含的思想就是将处理中可变的一部分抽象为一个function,并将其作为一个参数传入.这是高度抽象的方法,所带来的表达的威力也是无与伦比的.下面举一个例子,实现CPS描述的fold函数.在此之前需要简单介绍一下fold概念,在FP中这是一个非常有效的处理list的工具.一般它的signature是fold(f,initial,li…
我们在学数据结构的时候必然会接触栈(Stack),而栈有一个重要的应用是在程序设计语言中实现递归.递归用途十分广泛,比如我们常见的阶乘,如下代码: 1234 public static int (int n) { if (n == 1) return 1; return n * func1(n - 1);} 就可以用递归实现,而且实现相当简洁.如果要计算n的阶乘,那么只需知道n-1的阶乘再乘以n,同理依次类推,直到当我们计算2的阶乘的时候,只需知道1的阶乘,显然这是递归终止条件,再层层向上返回,…