scala:将具有较大前任元素的元素从列表中删除的函数

时间:2018-11-19 15:45:46

标签: scala

我想在scala biggerPredecessor中编写一个尾部递归函数,以从列表中删除具有较大前任元素的元素。

例如:

(1,3,2,5,7)

应导致:

(1,3,5,7)

这是我到目前为止所拥有的,但是现在我被卡住了。

def biggerPredecessor(xs: List[Int]) : List[Int] = (xs) match
  {
    def finalElements(ys: List[Int], xs: List[Int]) : List[Int] = (ys, xs) match
    {
      case (Nil, x::xs) => finalElements(new List(x), xs)
      case (y::ys, x::xs) if x > y => x::xs // insert in reverse order into list
      case (y::ys, Nil) => // ...
    }
  }

4 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

def biggerPredecessor(xs: List[Int]): List[Int] = {
    @tailrec
    def finalElements (xs: List[Int], acc: List[Int] ): List[Int] = xs match {
        case Nil => acc
        case head :: tail => finalElements(tail, if(acc.headOption.getOrElse(0) > head) acc else head :: acc)
    }

    finalElements(xs, List.empty[Int]).reverse
}

或者更简洁一点,使用foldLeft

foldLeft(List.empty[Int])((acc, elem) => if(acc.lastOption.getOrElse(0) > elem) acc else acc :+ elem))

答案 1 :(得分:2)

我的解决方案将使用foldLeft

  val seq = List(1,3,2,5,7)

  val result = seq.foldLeft(List[Int]()){
    case (Nil, x: Int) => List(x)
    case (ys, x) if x > ys.last => ys :+ x
    case (ys, x) => ys
  }

  println(result)

以下是Luis MiguelMejíaSuárez建议的版本:

 val result2 = seq.foldLeft(List.empty[Int]){
    case (Nil, x) => List(x)
    case (ys, x) if x > ys.head => x :: ys
    case (ys, x) => ys
  }.reverse

好,这是jwvh建议的递归翻译:

  def biggerPredecessor(list: List[Int],
                        results: List[Int] = List.empty[Int]): List[Int] = (list, results) match {
    case (Nil, _) => results.reverse
    case (x::xs, Nil) => biggerPredecessor(xs, List(x))
    case (x::xs, y::_) if x > y => biggerPredecessor( xs,x :: results)
    case (_::xs, _) => biggerPredecessor(xs, results)
  }

  println(biggerPredecessor(seq))

完成列表后,还需要另外一种情况。

您可以将其粘贴到Scalafiddle中并检查一下自己。

答案 2 :(得分:1)

如果您只需要非递归解决方案,那么这里是:

def biggerPredecessor(ls: List[Int]) =
  ls.take(1) ++ ls
    .zip(ls.drop(1))
    .collect {
      case (l,r) if !(l>r) => r
    }

答案 3 :(得分:0)

我非常喜欢sliding函数:

def biggerPredecessor(xs: List[Int]) : List[Int] =
  (null.asInstanceOf[Int] :: xs) // null is the sentinel, because first item is always included
    .sliding(2)
    .flatMap {
      case List(a,b) => if (a > b) None else Some(b)
      case List(_) => None // special handling for empty xs
    }
    .toList


println(biggerPredecessor(List()))
println(biggerPredecessor(List(1)))
println(biggerPredecessor(List(1,2)))
println(biggerPredecessor(List(2,1)))
println(biggerPredecessor(List(1,3,2,5,7)))

ScalaFiddle