Scala 函数式编程_递归_Recursion

Scala 函数式编程_递归_Recursion


引用:http://www.ibm.com/developerworks/cn/java/j-lo-funinscala1/


递归一:为一组整数列求和

递归思想:如何为一组整数数列求和?按照通常命令式编程的思维,我们会采用循环,依次遍历列表中的每个元素进行累加,最终给出求和结果。这样的程序不难写,稍微具备一点编程经验的人在一分钟之内就能写出来。这次我们换个思维,如何用递归的方式求和?为此,我们不妨把问题简化一点,假设数列包含 N 个数,如果我们已经知道了后续 N – 1 个数的和,那么整个数列的和即为第一个数加上后续 N – 1 个数的和,依此类推,我们可以以同样的方式为 N – 1 个数继续求和,直到数列为空,显然,空数列的和为零。听起来复杂,事实上我们可以用一句话来总结:一个数列的和即为数列中的第一个数加上由后续数字组成的数列的和。

scala 表示如下,

println("recursion test")

//xs.head 返回列表里的头元素,即第一个元素
//xs.tail 返回除头元素外的剩余元素组成的列表
def sum(xs: List[Int]): Int = if (xs.isEmpty) 0 else xs.head + sum(xs.tail)

val list = List(1,2,3,4,67,9,6,9876,5678)
println(sum(list))

运行结果,

E:\test-scala>scala Recursion.scala
recursion test
15646


递归二:求数列的最大值

递归思想:这个数列求和的例子并不是特别的,它代表了递归对于列表的一种普遍的处理方式,即对一个列表的操作,可转化为对第一个元素,及剩余列表的相同操作。比如我们可以用同样的方式求一个数列中的最大值。我们假设已经知道了除第一个元素外剩余数列的最大值,那么整个数列的最大值即为第一个元素和剩余数列最大值中的大者。这里需要注意的是对于一个空数列求最大值是没有意义的,所以我们需要向外抛出一个异常。当数列只包含一个元素时,最大值就为这个元素本身,这种情况是我们这个递归的边界条件。一个递归算法,必须要有这样一个边界条件,否则会一直递归下去,形成死循环。

scala 表示如下,

def max(xs: List[Int]): Int = {
  if (xs.isEmpty)
    throw new java.util.NoSuchElementException
  if (xs.size == 1)
    xs.head
  else
  if (xs.head > max(xs.tail)) xs.head else max(xs.tail)
}

val list = List(1, 2, 3, 4, 67, 9, 6, 9876, 5678)
println(max(list))

运行结果,最后求出最大值9876


递归三:反转字符串

递归思想:让我们再看一个例子:如何反转一个字符串?比如给定一个字符串"abcd",经过反转之后变为 "dcba"。同样的,我们可以做一个大胆的假设,假设后续字符串已经反转过来,那么接上第一个字符,整个字符串就反转过来了。对于一个只有一个字符的字符串,不需要反转,这是我们这个递归算法的边界条件。

scala实现如下,

def reverse(xs: String): String =
  if (xs.length == 1) xs else reverse(xs.tail) + xs.head

println(reverse("abcdefg"))

比如,反转字符串abcdefg。


递归四:快速排序

递归思想:最后一个例子是经典的快速排序,读者可能会觉得这个例子算不上简单,但是我们会看到,使用递归的方式,再加上 Scala 简洁的语言特性,我们只需要短短几行程序,就可以实现快速排序算法。快速排序算法的核心思想是:在一个无序列表中选择一个值,根据该值将列表分为两部分,比该值小的那一部分排在前面,比该值大的部分排在后面。对于这两部分各自使用同样的方式进行排序,直到他们为空,显然,我们认为一个空的列表即为一个排好序的列表,这就是这个算法中的边界条件。为了方便起见,我们选择第一个元素作为将列表分为两部分的值。

scala 实现如下,

def quickSort(xs: List[Int]): List[Int] = {
  if (xs.isEmpty) xs
  else
    quickSort(xs.filter(x => x < xs.head)) ::: xs.head :: quickSort(xs.filter(x => x > xs.head))
}

val list = List(1,2,3,4,67,9,6,9876,5678)
println(quickSort(list))


=====================END=====================


你可能感兴趣的:(Scala 函数式编程_递归_Recursion)