递归函数
来源:互联网 发布:dx 1vb大屏幕显示器 编辑:程序博客网 时间:2024/05/18 03:22
- 定义
- 缺点
- 尾递归
- 实例
- Trampoline类型递归函数
定义
直接或间接调用函数本身的函数称为递归函数。
递归是函数式编程的特点,也是优雅地实现很多算法的强大工具。在函数式编程中递归是实现“循环”的唯一方法,这是因为你无法修改循环变量。
缺点
- 反复调用函数带来的开销;
- 栈溢出的风险。
尾递归
在递归函数中,若递归调用是整个函数中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归函数就是尾递归。
尾递归是一种能把函数优化为循环的最重要的一种递归,可以消除递归函数潜在的栈溢出风险,并消除函数调用开销进而提升效率。
JVM和许多其它语言环境目前并不对尾递归做优化,但scalac则可以。
实例
import scala.annotation.tailrecdef factorial(i: BigInt) = { @tailrec def fact(i: BigInt, accumulator: BigInt): BigInt = { if(1 == i) accumulator else fact(i - 1, i * accumulator) } fact(i, 1)}
将标记@tailrec添加到尾递归函数时,编译器会对其做尾递归优化。若添加此标记的函数并不是尾递归函数,则编译器会抛出错误。
当一个调用了自身的方法,有可能被子类型中的同名方法覆写时,尾递归是无效的。所以,尾递归的方法必须用private或final关键字声明,或者将其嵌套在另一个方法中。
Scala采用的是局部作用域类型推断,无法推断出递归函数的返回类型。因此需要显式写出其返回类型。
定义一个嵌套的尾递归函数,将累加值作为参数,是将很多普通递归算法转化为尾递归的实用技巧。
Trampoline类型递归函数
Trampoline(原意“蹦床”):是指通过依次调用各个函数完成一系列函数之间的循环,也即在多个函数之间反复来回调用。Scala库中的尾递归对象(scala.util.control.TailCalls)可以将trampoline转化为循环。
import scala.util.control.TailCalls._def isEven(xs: List[Int]): TailRec[Boolean] = { if(xs.isEmpty) done(true) else tailCall(isOdd(xs.tail))}def isOdd(xs: List[Int]): TailRec[Boolean] = { if(xs.isEmpty) done(false) else tailCall(isEven(xs.tail))}isEven((1 to 2).toList).result //true
参考《Scala程序设计》第二版
阅读全文
1 0
- [递归]递归函数
- 递归函数
- 递归函数
- 递归函数
- 递归函数
- 递归函数
- 递归函数
- 函数递归
- 递归函数
- 递归函数
- 递归函数
- 递归函数
- 函数递归
- 递归函数
- 递归函数
- 递归函数
- 递归函数
- 递归函数
- NOIP2002 洛谷P1033 自由落体
- Linux下安装和运行Wireshark
- url传递中文乱码问题
- where字句有关的优化+使用where字句代替having字句
- 顺序栈的初始化,进栈、出栈、求长、判空、访顶、遍历、清空、销毁
- 递归函数
- [leetcode]605. Can Place Flowers
- 如何使用nginx做反向代理服务器?
- Android之使用串口通信及协议解析
- 在CentOS 上 调试 MySQL-5.7.x 或者 MySQL-8.0 源码
- python 3.6X安装notebook后无法打开的解决办法
- 如何学习计算机编程语言
- 【Python】6“dict和set“
- Android-x86-7.1.1