【问题标题】:Kadane algorithm in Scala explanationScala 中的 Kadane 算法解释
【发布时间】:2020-03-13 18:22:58
【问题描述】:

我有兴趣学习如何使用 foldLeft 函数在 scala 中实现 Kadane(最大子数组和)算法。我在堆栈溢出时运行了this 示例,但是我不确定我是否理解该算法的确切作用。算法是这样的:

someArray.foldLeft(0 -> 0) {
      case ((maxUpToHere, maxSoFar), n) => val maxEndingHere = 0 max maxUpToHere + n
        maxEndingHere -> (maxEndingHere max maxSoFar)
    }._2

{} 中包含的内容是需要应用于每个元素的 lambda 函数吗?还有这条线究竟做了什么maxEndingHere -> (maxEndingHere max maxSoFar)?为什么括号中的括号用空格分隔?感谢您的帮助,如果我的问题太无知,我很抱歉,但我是 Scala 新手

【问题讨论】:

    标签: scala data-structures sub-array foldleft kadanes-algorithm


    【解决方案1】:

    首先,您需要了解foldLeft 是什么。这个函数的意思是通过传递组合操作和初始元素将集合折叠成单个值:

    // Think of applying op(op(op(…), z) from left to right:
    def foldLeft[B](z: B)(op: (B, A) ⇒ B): B
    

    现在,让我们看看您的foldLeft 中发生了什么。首先,0 -> 0 被传递。这意味着初始元素的类型B是一个元组(Int, Int),其值为(0, 0)

    其次,左括号定义了一个函数。在 scala 中,您可以使用花括号传递它。因此,函数需要 (B, A) 的参数,在我们的例子中,B 类型是元组 (Int, Int)A 类型是数组元素的类型,即 Int

    所以,当你可以像这样翻译你的代码时:

    someArray.foldLeft(0 -> 0) {
      (tuple: (Int, Int), element: Int) => //the body
    }
    

    现在,在 Scala 中,您可以通过应用提供的模式使用 case 关键字创建部分函数。我们案例中的模式通过将变量 maxUpToHeremaxSoFar 绑定到元组元素并将 n 绑定到数组元素来匹配提供的参数。

    因此,该函数将从数组中获取每个元素,将其与提供的元组一起应用,并将其传递给下一个应用程序,直到数组被完全处理。现在,让我们看看函数体中发生了什么:

    val maxEndingHere = 0 max maxUpToHere + n
    maxEndingHere -> (maxEndingHere max maxSoFar)
    

    请记住,我们的函数应该返回下一个B 以申请使用数组中的元素进行调用。 B 在我们的例子中是一个元组。因此,想法是将序列的整体最大值和局部最大值存储在一个元组中。

    maxEndingHeremax 之间的 0 和先前计算与数组的当前元素 n 的总和。如果当前元素为负数,它将减少最大序列,因此在最大比较结果上产生0,从而重置累加值。

    然后,我们只需使用序列maxEndingHere 的新计算总和以及当前值与目前计算的值之间的最大值(因此命名为maxSoFar)创建新元组。

    最后,我们只需通过调用._2 来获取计算元组的第二个值。

    【讨论】:

      【解决方案2】:
      {}
      

      lambda 函数将应用于数组中的每个元素

      maxEndingHere -> (maxEndingHere max maxSoFar)
      

      它将 maxUpToHere 设置为 maxEndingHere 并将 maxSoFar 设置为 maxEndingHere 和 maxSoFar 之间的最大值的结果以进行下一次迭代

      所以要干运行代码:对于下面的数组,对数组的每个元素运行如下代码

      someArray: Array[Int] = Array(5, 2, -10, 6, 8)
      
      For element n = 5
      maxUptoHere = 0
      maxSoFar = 0
      n = 5
      maxEndingHere = 5
      
      For element n = 2
      maxUptoHere = 5
      maxSoFar = 5
      n = 2
      maxEndingHere = 7
      
      For element n = -10
      maxUptoHere = 7
      maxSoFar = 7
      n = -10
      maxEndingHere = 0
      
      For element n = 6
      maxUptoHere = 0
      maxSoFar = 7
      n = 6
      maxEndingHere = 6
      
      For element n = 8
      maxUptoHere = 6
      maxSoFar = 7
      n = 8
      maxEndingHere = 14
      
      res15: Int = 14
      

      【讨论】:

        猜你喜欢
        • 2012-02-20
        • 2011-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        相关资源
        最近更新 更多