Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将查找列表最大数量的递归实现可视化?_Java_Scala_Recursion - Fatal编程技术网

Java 如何将查找列表最大数量的递归实现可视化?

Java 如何将查找列表最大数量的递归实现可视化?,java,scala,recursion,Java,Scala,Recursion,我有一个递归函数来查找列表中的最大数。我根据自己曾经遇到的一个技巧编写了这个函数。提示建议,当尝试在整数列表中查找最大整数时,应: 覆盖基本情况 想象一下,如果有另一个函数给出列表尾部的最大值 用你的函数替换虚函数 所以伪代码看起来像 def max(somelist: List[Int]): Int = { // base case 1: empty then error out if (somelist.isEmpty) { Error out } // base ca

我有一个递归函数来查找列表中的最大数。我根据自己曾经遇到的一个技巧编写了这个函数。提示建议,当尝试在整数列表中查找最大整数时,应:

  • 覆盖基本情况
  • 想象一下,如果有另一个函数给出列表尾部的最大值
  • 用你的函数替换虚函数
  • 所以伪代码看起来像

    def max(somelist: List[Int]): Int = {
      // base case 1: empty then error out
      if (somelist.isEmpty) {
       Error out
      }
      // base case 2: if the list has one elements 
      if (somelist.tail.isEmpty) {
        somelist.head
      }
      // Otherwise imagine I have a function that return the max of the tail of the list
      // call it imaginary_max(tailOfList).
      // get the max of the tail and then compare to the head of your list
      // and return the appropriate result.
      // replace imaginary_max with max and it works
    
      else {
        val m = max(somelist.tail);      
        if (somelist.head > m) {
          somelist.head
        }
        else {
          m
        }
      }
    }
    

    这是可行的,但我很难想象背景中发生了什么,尤其是当我试图向其他人解释时。感谢您的帮助和指导

    如果考虑堆栈,递归的可视化通常是最容易的

    假设我正在尝试使用您的算法查找
    [1,2,5,0]
    的最大值。您可以这样设想:

    max( [0] ) => 0
    max( [5, 0] ) => 5
    max( [2, 5, 0] )
    max( [1, 2, 5, 0] )
    

    堆栈的底部是您开始的地方,您可以将输入传递到
    max()
    。第一次调用的结果是调用列表尾部的
    max
    ,即
    [2,5,0]
    。同上,下一级除外,下一级为基本情况。因此,在堆栈的顶部,返回数字5。数字5“从堆栈中掉出来”作为答案。

    在试图理解递归的工作原理时,使用堆栈框架的概念是很有帮助的。简言之,堆栈框架只是一块内存,用于存储传递到函数中的参数值以及该函数中定义的局部变量。任何时候调用函数时,该函数的新堆栈帧都会位于当前函数的堆栈帧之上,以此类推,继续调用函数。当当前函数结束时,它的堆栈帧从当前“调用堆栈”中“弹出”,这意味着与调用函数相关联的变量现在处于“堆栈顶部”或可供使用

    以下图片可能有助于展示:


    在本例中,看起来调用堆栈实际上在向下增长,但概念是相同的。

    这是我正在实现的工具的一个很好的用例,所以我很快调整了您的源代码。 最终的可视化不需要一些痕迹,但我添加了它们以防万一:

    package com.example
    
    import org.stellabs.scart.tracing._
    
    object KillerApp extends App{
    
      def max(somelist: List[Int]): Int =           s"max([${somelist mkString ", "}])".e_++:
      {
        // base case 1: empty then error out
        if (somelist.isEmpty) {
         ???
        }
        // base case 2: if the list has one elements 
        if (somelist.tail.isEmpty) {
          somelist.head
        }
        // Otherwise imagine I have a function that return the max of the tail of the list
        // call it imaginary_max(tailOfList).
        // get the max of the tail and then compare to the head of your list
        // and return the appropriate result.
        // replace imaginary_max with max and it works
    
        else {                                      ;|++: $$ s"recursion >> max(${somelist.tail})"
          val m = max(somelist.tail)                ;|++: $$ s"recursion << m = $m"
          if (somelist.head > m) {
            somelist.head
          }
          else {
            m
          }
        }
      }
    
      // MAIN
      max( {args map {_.toInt}}.toList )            e_++: 'main
    
    }
    

    干杯。

    我看不到的是数字之间什么时候进行比较。它是在值开始从堆栈中弹出时发生的吗?不,它发生在max()中function@awm,它在值开始从堆栈中弹出时发生。需要注意的重要一点是,是的,你是对的,所有的调用都发生在任何比较之前。。。当函数调用return时,返回值被分配给
    m
    ,此时将进行比较。。。我希望我解释得很好…是的。我很久以前在cs学校就处理过这个问题。我觉得我对递归的理解是公平的,但不是100%。可视化递归的最好方法是交互式的。您可以使用调试器逐步完成代码并查看各种变量的值。这还允许您查看每个递归调用如何包含自己的参数和局部变量,这些参数和局部变量因调用而异,因此每个函数调用独立于其他函数调用。我没有使用scala,但我假设您可以使用Eclipse或IntelliJ逐步完成这段代码。这就是我的建议。@Jake我确信这会逐渐变得更好,但不久前IDEs中的交互式调试器(我使用Eclipse)还不成熟。这就是为什么我从跟踪值开始,这并不理想,但对于您提到的是一个实际的解决方法。+1用于添加缩进、函数调用、函数返回值和结果的比较操作。为了演示如何运行该示例,请使用git克隆完成。。。
    mkdir -p ~/tmp
    cd ~/tmp
    git clone https://github.com/stellabs/scart.git
    cd scart
    git checkout v0.02.001
    cd sbt
    
    cd scart
    sbt publishLocal
    cd ..
    
    cd template/inline
    mv build.sbt build.sbt.ori
    sed -e 's/all-last/as-is/' build.sbt.ori > build.sbt
    
    # EDIT ./killerapp/src/KillerApp.scala,
    # REPLACE CONTENTS WITH THE SOURCE SHOWN ABOVE
    # SAVE
    
    sbt run
    # ...
    > max([])<scala.NotImplementedError: an implementation is missing>
    [error] (run-main) scala.NotImplementedError: an implementation is missing
    # ...
    
    sbt "run 1 2 5 0"
    # ...
    > > recursion >> max(List(2, 5, 0))
    > > > recursion >> max(List(5, 0))
    > > > > recursion >> max(List(0))
    > > > > max([0])=0
    > > > > recursion << m = 0
    > > > max([5, 0])=5
    > > > recursion << m = 5
    > > max([2, 5, 0])=5
    > > recursion << m = 5
    > max([1, 2, 5, 0])=5
    > main=5
    # ...
    
      // MAIN
                                                    'main.e_++:
      {
        max( {args map {_.toInt}}.toList )            
      }