【发布时间】:2012-07-04 00:31:09
【问题描述】:
我有点讨厌递归(这就是我研究这个的原因)而且我很难弄清楚如何做到这一点:("Hello" foldLeft(1))((x, y) => x * y.toInt) 递归。有什么想法吗?
【问题讨论】:
-
更好:
"Hello".map(_.toInt).product
我有点讨厌递归(这就是我研究这个的原因)而且我很难弄清楚如何做到这一点:("Hello" foldLeft(1))((x, y) => x * y.toInt) 递归。有什么想法吗?
【问题讨论】:
"Hello".map(_.toInt).product
scala> def r(s : String) : Int = {
| s match {
| case "" => 1
| case _ => s.head.toInt * r(s.tail)
| }
| }
r: (s: String)Int
scala> r("hello")
res4: Int = 714668928
【讨论】:
@tailrec注解,如果不是,编译器会报错
我将另一个答案转换为我认为的尾递归版本:
@tailrec
def r(acc: Int, s: String): Int = {
s match {
case "" => acc
case _ => r(s.head.toInt * acc, s.tail)
}
}
print(r(1, "hello"))
有关将此类函数转换为尾递归格式的一般建议,请参阅此答案:
【讨论】:
r(s:String, acc:Int = 1),这样调用函数的时候就不用初始化累加器了。
这是一个使用累加器的尾递归版本。这个版本也有一个干净的 API。
import scala.annotation.tailrec
def unicodeProduct(string: String): Int = {
@tailrec
def unicodeProductAcc(string: String, acc: Int): Int = {
string match{
case "" => acc
case _ => unicodeProductAcc(string.tail, string.head.toInt * acc )
}
}
unicodeProductAcc(string, 1)
}
scala> :load unicodeProduct.scala
Loading unicodeProduct.scala...
import scala.annotation.tailrec
unicodeProduct: (string: String)Int
scala> unicodeProduct("hello")
res0: Int = 714668928
【讨论】:
过时了,但下面有什么问题?
def product_recursive(s: String): Long = {
if (s.length == 1)
s.head.toLong
else
s.head.toLong * product_recursive(s.tail)
}
【讨论】:
""。