1

这个函数应该返回列表中所有数字的总和,但是当我运行它时,我总是会返回ans=0

def sum(st: List[Int]): Int = {
  var ans=0 

  def combine(st: List[Int], ans:Int): Int = {
    if (st.isEmpty) ans else combine(st.tail, ans)        
  }
  ans
}

它有什么问题?

4

5 回答 5

5

您需要将列表的头部添加到ans. 目前您正在递归但实际上并未使用列表的头部。

例如,我认为您需要类似下面的内容,其中您将列表的头部添加到其余部分的总和中。

scala> def sum(st: List[Int]): Int = 
     | {
     | if (st.isEmpty) {
     |    0
     | }
     | else {
     |    st.head + sum(st.tail)
     | }
     | }
sum: (st: List[Int])Int
于 2013-03-26T14:13:53.190 回答
3

1)你没有调用内部方法 combine - 你只是返回 ans,因为它被初始化为 0。

2) combine 并没有真正做任何事情

我认为您要编写的代码如下:

def sum(st: List[Int]): Int = {
  def combine(st: List[Int], ans:Int): Int = {
    if (st.isEmpty) ans else combine(st.tail, ans + st.head)        
  }
  combine(st, 0)
}

但当然更短的版本是:

st.foldLeft(0)(_ + _)

要不就

st.sum

它使用 Numeric 的标准类型类实例:IntIsIntegral:

http://www.scala-lang.org/api/current/index.html#scala.math.Numeric $$IntIsIntegral$

于 2013-03-26T15:34:06.953 回答
2

您在 method 中定义了一个方法combinesum但您没有调用combine(除了 within combine,因此它永远不会被调用)。如果不调用该方法,则不会执行;仅仅定义方法并不意味着它已被执行。

如果你想用函数式编程,你也应该避免使用可变变量(var);请改用不可变值 ( val)。

此外,您的combine方法不会对任何内容求和(它不会ans在任何地方修改,也不会使用列表中的任何值)。

于 2013-03-26T14:51:08.683 回答
1

我同意 Brian 关于为什么您的解决方案不起作用的回答。

此外,使用 foldLeft 使用 Scala 的 Sequence of Scala(List 实现)的 API 有一种更短的方法:

def sum(st: List[Int]): Int = {
    st.foldLeft(0)(_ + _)
}
于 2013-03-26T14:52:12.137 回答
0

foldLeft,甚至更好, sum 是 hedefalk 提到的首选选项。

于 2013-03-26T17:11:19.893 回答