【问题标题】:Recursive function - reverse iterate through List递归函数 - 反向遍历 List
【发布时间】:2020-09-26 11:07:47
【问题描述】:

我最近开始在 SCALA 上学习函数式编程。我使用递归函数打印列表的元素,现在我想打印从末尾开始的元素("Ann" ...)但也使用递归函数,有人可以帮我转换代码吗?

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);
    }
  }
}

【问题讨论】:

    标签: list scala recursion functional-programming scala-collections


    【解决方案1】:

    您可以使用以下定义:

    def printNames(names: List[String]): String = {
      if(names.isEmpty) ""
      else printNames(names.tail) + " " + names.head
    }
    

    请注意,此实现不是尾递归的,无法由 scala 编译器优化。我强烈建议对生成的String 使用累加器。

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

    def printNames(names: List[String]): StringBuilder = {
      if(names.isEmpty) new StringBuilder("")
      else printNames(names.tail).append(" ").append(names.head)
    }
    

    【讨论】:

    • 值得一提的是,串联字符串非常昂贵。使用 StringBuilder 作为累加器可能会更好。
    • List reverse with mkString 将给出所需的结果,而 mkString 使用 Stringbuilder stackoverflow.com/questions/16447681/…
    • @ShankarShastri 是的,位 OP 正在寻找递归解决方案
    • @Andronicus,我已经更新了答案。
    【解决方案2】:
    def printNames(names: List[String]): String = names.reverse.mkString(" ")
    

    您可以反转名称列表,然后使用带有空格的 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 sn-p:

    <script src="https://scastie.scala-lang.org/shankarshastri/0dxWt7K3S8CkkAffliLICQ/7.js"></script>

    【讨论】:

      猜你喜欢
      • 2021-10-30
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多