【问题标题】:Is it possible to update a variable in foldLeft function based on a condition?是否可以根据条件更新 foldLeft 函数中的变量?
【发布时间】:2016-05-24 13:11:37
【问题描述】:

我正在尝试编写 scala 代码,该代码从给定数组的连续子数组中给出最大总和。例如,val arr= Array(-2, -3, 4, -1, -2, 1, 5, -3)。在这个数组中,我需要获得最大的连续子数组总和,即 4+(-1)+(-2)+(1)+5 = 7。我编写了以下代码来获得这个结果。

scala> arr.foldLeft(0) { (currsum,newnum) => if((currsum+newnum)<0) 0 else { if(currsum<(currsum+newnum)) (currsum+newnum) else currsum }}
res5: Int = 10

但与实际结果有偏差,因为随着计数/求和的进行,我无法更新 maximum_so_farvalue。由于我使用foldLeft 来执行此功能,是否有可能仅在连续子数组元素的总和大于之前的 max_sum 时更新maximum_so_far变量?

reference link for better understanding of scenario

【问题讨论】:

  • “连续子数组”是什么意思?
  • @Jubobs ,表示最大值。 sum 应该包括来自子数组/数组的连续元素。这意味着来自给定数组的 4+(-1)+(-2)+(1)+5 =7 但不是 4+1+5 = 10 的总和。为了更好地理解场景,请查看上述问题底部提供的链接。谢谢
  • 您的代码没有maximum_so_far 值,因此不清楚您的意思。但通常在 foldLeft 中,您不会“更新”变量,而是将累加器中的新值传递给下一次迭代。因此,不要只传递currsum,而是传递一对(currsum, maxsofar) 并根据需要提取值。

标签: scala sub-array foldleft


【解决方案1】:

显然,您必须在输入数据中传播两个值才能进行此计算,就像在命令式情况下需要做的那样:

arr.foldLeft((0,0)){
  case ((maxSum, curSum), value) => {
    val newSum = Math.max(0, curSum + value)
    (Math.max(maxSum, newSum), newSum)  
  }
}._1

另一种方法是计算中间结果(如果需要,可以延迟计算),然后选择最大值:

arr.toIterator.scanLeft(0){
  case (curSum, value) =>
    Math.max(0, curSum + value)
}.max

【讨论】:

  • 这会很有帮助。谢谢
猜你喜欢
  • 1970-01-01
  • 2021-08-06
  • 2023-03-17
  • 1970-01-01
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多