[toc]
## Scala递归编程练习
> Scala 是运行在 Java 虚拟机(Java Virtual Machine)之上,因此具有如下特点:
>
> 1. 轻松实现和丰富的 Java 类库互联互通。
> 2. 它既支持面向对象的编程方式,又支持函数式编程。
> 3. 它写出的程序像动态语言一样简洁,但事实上它确是严格意义上的静态语言。
> 4. Scala 就像一位武林中的集大成者,将过去几十年计算机语言发展历史中的精萃集于一身,化繁为简,为程序员们提供了一种新的选择。设计者`马丁·奥得斯基` 希望程序员们将编程作为`简洁,高效,令人愉快的工作`。同时也让程序员们进行关于编程思想的新的思考。
### 1. 编程范式
> 1. 在所有的编程范式中,面向对象编程(Object-Oriented Programming)无疑是最大的赢家。
> 2. 但其实面向对象编程并不是一种严格意义上的编程范式,严格意义上的编程范式分为:命令式编程(Imperative Programming)、函数式编程(Functional Programming)和逻辑式编程(Logic Programming)。`面向对象编程只是上述几种范式的一个交叉产物`,更多的还是继承了`命令式编程`的基因。
> 3. 在传统的语言设计中,只有命令式编程得到了强调,那就是程序员要告诉计算机应该怎么做。而递归则通过灵巧的函数定义,告诉计算机做什么。因此在使用命令式编程思维的程序中,是现在多数程序采用的编程方式,递归出镜的几率很少,而在函数式编程中,大家可以随处见到递归的方式。
> 4. ==Scala提倡函数式编程(递归思想)==
> 5. scala中循环不建议使用while和do...while,而建议使用递归。
### 2. 应用实例
#### 实例一
> 使用while求1-100000000(一亿)的求和
~~~~scala
/**
* 使用while求1-100000000(一亿)的求和
*/
def getRes(): Unit = {
var res = BigInt(0)
var num = BigInt(1)
// 一亿条数据
var maxVal = BigInt(100000000)
while (num <= maxVal) {
res += num
num += 1
}
println(res)
}
~~~~
> 使用递归完成:测试发现超10000就会报SOF
~~~scala
/**
* 使用递归完成
* @param n
* @param max
* @return
*/
def getRecurisveRes(n: BigInt, max: BigInt): BigInt = {
if (n == max) {
n
} else {
n + getRecurisveRes(n + 1, max)
}
}
~~~
#### 实例二
> 使用递归求List中的最大值:
~~~~scala
/**
* 使用递归完成求List中的最大值
* @param list
* @return
*/
def getMax(list: List[Int]): Int = {
if (list.isEmpty) {
throw new java.util.NoSuchElementException
}
if (list.size == 1) {
list.head
} else if (list.head > getMax(list.tail)) {
list.head
} else {
getMax(list.tail)
}
}
~~~~
#### 实例三
> 使用递归完成字符串的反转
~~~~scala
/**
* 使用递归完成字符串的反转
* @param str 输入的字符串
* @return
*/
def strReverse(str: String): String = {
if (str.length == 1) {
str
} else {
strReverse(str.tail) + str.head
}
}
~~~~
#### 实例四
> 递归求阶乘
```scala
/**
* 递归求阶乘
* @param n
* @return
*/
def getFactorial(n: BigInt): BigInt = {
if (n == 1) {
n
} else {
n * getFactorial(n - 1)
}
}
```
#### 实例五
> 递归求斐波那契数列
~~~~scala
/**
* 递归求斐波那契数列
* @param n
* @return
*/
def getFib(n: Int): Int = {
count += 1
if (n == 1 || n == 2) {
1
} else {
getFib(n - 1) + getFib(n - 2)
}
}
~~~~
### 3. 测试代码
~~~~scala
import java.util.Date
import java.text.SimpleDateFormat
/**
* @Date 2021/4/4 15:55
* @Version 10.21
* @Author DuanChaojie
*/
object RecursiveDemo01 {
var count = 1
def main(args: Array[String]): Unit = {
val start: Date = new Date()
val dateFormat: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val startDate = dateFormat.format(start)
println(startDate)
//getRes()
//println(getRecurisveRes(1, BigInt(1000)))
//println(getMax(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 35, 3, 5)))
//println(strReverse("HELLO"))
//println(getFactorial(13))
/**
* 1 1 2 ...
* 分析函数都调用了多少次
*
* 输入数:4 5 6 7 8 9 10 11 12 13 14 15 21 40
* 结 果:3 5 8 13 21 34 55 89 144 233 377 610 10946 102334155
* 调用数:6 10 16 26 42 68 110 178 288 466 754 1220 21892 204668310
*/
println(getFib(40))
println(count)
val end: Date = new Date()
val endDate = dateFormat.format(end)
println(endDate)
}
}
~~~~
## ☆