如何使用递归在scala中找到列表/数组中的最大差异?

时间:2018-02-07 18:33:39

标签: scala recursion

我是Scala的初学者,我正试图解决类似的问题。

https://www.geeksforgeeks.org/maximum-difference-between-two-elements/

我已经编写了该站点中编写的代码的Scala版本。这是我的代码:

object stock{
def getMaxP(Li:List[Int]):Int={

var max_diff=Li(1)-Li(0)
var min_ele=Li(0)

for(i<-0 until Li.length){      
  if(Li(i)-min_ele>max_diff) max_diff=Li(i)-min_ele
  if(Li(i)<min_ele) min_ele=Li(i)
}

max_diff  
}

def main(args:Array[String]){
val li=List(10, 7, 5, 8, 11, 9)
println(getMaxP(li))
}

}

以上代码有效。但我想用递归来解决它,我更喜欢使用listname.tail函数。我可以将s_p_y.tai​​l传递给递归函数(因为s_p_y是一个列表)并解决它,但我不知道如何实现它。

这是我在网上找到的一个示例代码,它使用递归来查找max元素。

def max2(ints: List[Int]): Int = { 
@tailrec
def maxAccum2(ints: List[Int], theMax: Int): Int = {
  if (ints.isEmpty) {
    return theMax
  } else {
    val newMax = if (ints.head > theMax) ints.head else theMax
    maxAccum2(ints.tail, newMax)
  }
}
maxAccum2(ints, 0)
}

} 

3 个答案:

答案 0 :(得分:1)

典型的模式是集合上的模式匹配:

@annotation.tailrec
def getMaxp (li: List[Int], min: Int, dmax: Int): Int = li match {
    case Nil => dmax ???
    case x :: rest => getMaxP (rest, ???, ???)
}

def main(args:Array[String]){
    val li = List (10, 7, 5, 8, 11, 9)
    println (getMaxp (li, ???, ???))
}

什么是空案例 - 可能在列表的末尾,或者因为初始列表是空的?

getMaxp的参数2和3必须以某种方式与min,max和x(li(0))相关。

您可以调用其他函数,当然,您必须编写这些函数,以避免使用中间值来混淆空间。

在现实生活中,为了方便调用方法,你可以提供一个易于调用的界面,并处理内部的起始阶段并使用内部函数,这可以确保选择正确的起始值:

def getMaxp (li: List[Int]): Int = li match {

    @annotation.tailrec
    def getMaxp (li: List[Int], min: Int, dmax:Int): Int = li match {
        case Nil => ???
        case x :: rest => getMaxP (rest, ???, ???)
    }
    getMaxP (rest, ???, ???)
}

def main(args:Array[String]){
    val li = List (10, 7, 5, 8, 11, 9)
    println (getMaxp (li))
}

答案 1 :(得分:0)

感谢@user unknown的答案。这就是我用你的方法解决问题的方法。如果我能以任何方式改进我的代码,请告诉我。

object stock {


  def getMaxp(li: List[Int], maxd: Int, min: Int): Int = li match {
    case Nil => maxd
    case x :: rest => {
      var lmaxd: Int = maxd
      var lmin: Int = min
      if (x-min > maxd) lmaxd = x - min
      if (x < min) lmin = x
      getMaxp(rest, lmaxd, lmin)
    }
  }


  def main(args:Array[String]){
    val li =List(10, 7, 5, 8, 11, 9)
    val min=li(0)
    val maxd=li(1)-li(0)
    println (getMaxp(li,maxd,min))
  }

}

答案 2 :(得分:0)

此问题的直接解决方案是使用标准库中提供的方法。

List(2,5,10,6,4,8,1).combinations(2).map{case List(a,b) => b-a}.max //res0 = 8

但是当您尝试使用递归时,这是一个递归方法,它本身使用内部递归方法。

// find the maximum difference between any 2 numbers in a List[Int]
// (always: laterNumber - earlierNumer)
def maxDiff(li: List[Int], mx: Int = Int.MinValue): Int = {

  // test all subsequent elements against the current head
  def loop(subList: List[Int], subMax:Int = mx): Int =
    if (subList.isEmpty) subMax
    else loop(subList.tail, subMax max subList.head - li.head)

  if (li.isEmpty) mx  //all done
  else maxDiff(li.tail, loop(li.tail))
}

用法:

maxDiff(List(7, 9, 5, 6, 3, 2))  //res1: Int = 2

不需要var