官术网_书友最值得收藏!

Recursion

Recursion is used to implement recurring logic without relying on loops and the internal states associated with them. The recursive behavior is defined by two properties:

  • Base case: The simplest terminating case, in which no recursive calls are needed anymore
  • Recursive case: The set of rules describing how to reduce any other state to the base case

One of the possible examples for recursive implementation can be reversing a string. The two recursive properties would be:

  • The base case is an empty or single-char string. In this case, the reversed string is just the same string as given.
  • The recursive case for the string of length N can be reduced to the case of a string of length N-1 by taking the first char of the string and appending it to the reversed tail of the given string.

This is how we implement this logic in Scala:

def reverse(s: String): String = {
if (s.length < 2) s
else reverse(s.tail) + s.head
}

So, this is easier implemented than explained, right? 

One important aspect of our implementation in a recursive case is that it first makes the recursive call and then adds the rest of the string to the result. Such functions are head-recursive (but usually just called recursive) in the sense that the recursive call stays in the head of the computation. This works in a similar way to the depth-first algorithm, with the implementation first going down to the terminal case and then building up the result from the bottom up:

scala> println(reverse("Recursive function call"))
llac noitcnuf evisruceR

The nested function calls are naturally kept in the stack during runtime. Because of this, functions that work fine for inputs of smaller size might blow up the stack for bigger inputs, crashing the whole application:

scala> println(reverse("ABC" * 100000))
java.lang.StackOverflowError
at scala.collection.StringOps$.slice$extension(StringOps.scala:548)
at scala.collection.StringOps$.tail$extension(StringOps.scala:1026)
at ch03.Recursion$.reverse(Recursion.scala:7)
at ch03.Recursion$.reverse(Recursion.scala:7)
at ch03.Recursion$.reverse(Recursion.scala:7)
...

It is possible to increase the size of memory reserved for a stack in JVM, but often there is a better solution—tail recursion.

主站蜘蛛池模板: 芜湖县| 宝应县| 南陵县| 临颍县| 新昌县| 西平县| 灵川县| 江津市| 左云县| 二连浩特市| 桃源县| 朝阳县| 诸城市| 黑河市| 泰来县| 曲麻莱县| 南安市| 桦甸市| 炉霍县| 合川市| 余江县| 钦州市| 青川县| 仁化县| 临城县| 星子县| 凤凰县| 镶黄旗| 准格尔旗| 金溪县| 淮安市| 稻城县| 沛县| 绥宁县| 高阳县| 息烽县| 玛多县| 突泉县| 周口市| 洪泽县| 武川县|