我想在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) => // ...
}
}
答案 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)))