List 递归函数-反向遍历列表

List 递归函数-反向遍历列表,list,scala,recursion,functional-programming,scala-collections,List,Scala,Recursion,Functional Programming,Scala Collections,我最近开始学习SCALA上的函数式编程。我使用递归函数打印列表中的元素,现在我想打印从末尾开始的元素。。。但也使用递归函数,谁能帮我转换代码 object Scala { val names: List[String] = List("Adam", "Mick", "Ann"); def main(args: Array[String]) { println(printNames(names)) def (printNames (name: List[String] )

我最近开始学习SCALA上的函数式编程。我使用递归函数打印列表中的元素,现在我想打印从末尾开始的元素。。。但也使用递归函数,谁能帮我转换代码

object Scala {
  val names: List[String] = List("Adam", "Mick", "Ann");
  def main(args: Array[String]) {
    println(printNames(names))
    def (printNames (name: List[String] ) {
      if(names.isEmpty) ""
      else  names.head + (printNames(names.tail);
    }
  }
}

您可以使用以下定义:

def printNames(names: List[String]): String = {
  if(names.isEmpty) ""
  else printNames(names.tail) + " " + names.head
}
请注意,此实现不是尾部递归的,不能由scala编译器进行优化。我强烈建议对结果字符串使用累加器

Luis Miguel Mejía Suárez建议使用StringBuilder来避免昂贵的字符串连接:

def printNames(names: List[String]): StringBuilder = {
  if(names.isEmpty) new StringBuilder("")
  else printNames(names.tail).append(" ").append(names.head)
}
您可以反转名称列表,然后使用带有空格的mkString作为分隔符。上述方法可以在不递归的情况下实现同样的效果,因为默认情况下mkString使用StringBuilder

当您在寻找尾部递归解决方案时

import scala.annotation.tailrec

def printNames(names: List[String]): String = {
  @tailrec
  def printNamesHelper(
      names: List[String],
      acc: StringBuilder = new StringBuilder("")
  ): String = {
    names match {
      case Nil          => acc.toString.trim
      case head :: tail => printNamesHelper(tail, acc.append(head).append(" "))
    }
  }
  printNamesHelper(names)
}

def printNamesReverse(names: List[String]): String = {
  @tailrec
  def printNamesReverseHelper(
      names: List[String],
      accum: List[String] = List.empty
  ): String = {
    names match {
      case Nil          => printNames(accum)
      case head :: tail => printNamesReverseHelper(tail, head :: accum)
    }
  }
  printNamesReverseHelper(names)
}

printNames(List("Adam", "Framk"))
printNamesReverse(List("Adam", "Framk"))
在下面添加了scastie代码段:


值得一提的是,串接字符串非常昂贵。使用StringBuilder作为累加器可能很好。使用mkString的列表反转将给出所需的结果,而mkString使用StringBuilder@ShankarShastri是的,位OP正在寻找递归solution@Andronicus,我已经用同样的方法更新了答案。
import scala.annotation.tailrec

def printNames(names: List[String]): String = {
  @tailrec
  def printNamesHelper(
      names: List[String],
      acc: StringBuilder = new StringBuilder("")
  ): String = {
    names match {
      case Nil          => acc.toString.trim
      case head :: tail => printNamesHelper(tail, acc.append(head).append(" "))
    }
  }
  printNamesHelper(names)
}

def printNamesReverse(names: List[String]): String = {
  @tailrec
  def printNamesReverseHelper(
      names: List[String],
      accum: List[String] = List.empty
  ): String = {
    names match {
      case Nil          => printNames(accum)
      case head :: tail => printNamesReverseHelper(tail, head :: accum)
    }
  }
  printNamesReverseHelper(names)
}

printNames(List("Adam", "Framk"))
printNamesReverse(List("Adam", "Framk"))