【问题标题】:Java Array RecursionJava 数组递归
【发布时间】:2011-02-25 01:48:31
【问题描述】:

本次作业的目的是学习递归方法。对于这个特殊问题,我需要打印list 的值,每行一个。我需要完成的方法的骨架不能更改,如下:

public void list (String[] list) {

}

说明说辅助方法可以使这更容易编写。这是我的辅助方法:

public void print(String[] list, int index) {    
      if (index < list.length) {
          System.out.println(list[index]);
          print(list, index+1);
      }
}  

我只是想通过list方法调用print方法进行测试。我知道评分是通过脚本完成的,所以我再次无法更改列表方法的返回类型或参数。请原谅我的格式错误,并提前感谢您的帮助!

【问题讨论】:

  • @Jeremiah - 通常当你看到这样的荒谬的东西时,它只是一个初学者犯了代码格式错误。单击自己编辑,您可以查看他们哪里出错并修复它。我已经这样做了。错误在哪里通常很明显,如果你能解决它,它会对每个人都有帮助。
  • 去上课,集中注意力,看书,问问题,尝试作业,然后带着你所拥有的来这里。
  • @Shakedown 问题是人们已经把代码给了那个家伙:D 现在他不会去下一堂课,不会读这本书,既不提问,也不尝试作业:D
  • @Serhiy:你说得对,这就是人们急于给出答案只是为了在网站上获得声誉的问题。

标签: java recursion


【解决方案1】:

lots of good examplesrecursion in Java。你会从阅读这些中受益匪浅。首先阅读您的教科书,然后继续这些示例

【讨论】:

    【解决方案2】:

    如果我这样做,我会使用名为 print() 或类似名称的辅助方法。

    在思考程序的逻辑方面,想想你需要做什么:

    有一个辅助方法print()

    • 在新行上打印列表中的当前项
    • 然后它调用一个函数来打印列表中的下一个和后续项目,每个项目都换行

    您认为第二个功能可能是什么? 提示:它是递归的...

    【讨论】:

    • 给 Dan 的另一条提示:请随时对我们的回复发表评论,以便我们可以在此处进行对话以帮助您。我们不想给你作业的答案,但只要你努力增加你的理解和对话,我们愿意帮助你。
    【解决方案3】:

    我不会直接回答你,因为你不会从中学到任何东西。您可以创建变量来存储当前深度。创建 getter 和 setter 辅助方法以增加递归深度。您的方法列表将使用相同的数组调用自己,但只有在您检查深度不大于数组的大小之后。不要忘记增加每次调用的递归深度。

    【讨论】:

      【解决方案4】:

      考虑这样的递归解决方案:给定一堆东西(如列表),对其中的一个(如列表的第一个元素)做某事,然后将其余的东西传递给 处理其中一件事情的相同解决方案

      提示:您需要考虑在没有给出任何解决方案的情况下您的解决方案会做什么。

      提示 2:不要在每次递归时“切碎”数组,只需记下您在数组中的位置即可。

      【讨论】:

        【解决方案5】:

        当你进行递归时,写下你将如何使用循环执行相同的任务有时会很有帮助:

        public void list(String[] list) {
            for(int index = 0; index < list.length; index++) {
                System.out.println(list[index]);
            }
        } 
        

        现在,假设我们想要更接近递归解决方案。第一步可能是去掉for循环的内部部分:

        public void list(String[] list) {
            for(int index = 0; index < list.length; index++) {
                list(list, index);
            }
        }
        
        public void list(String[] list, int index) {
            System.out.println(list[index]);
        }
        

        好的,现在我们已经非常接近递归解决方案了。我们只需要执行循环处理的最后两个任务,递增index 并检查是否index &lt; list.length。这些看起来可能是减少步骤和基本案例的绝佳候选者。

        【讨论】:

          【解决方案6】:

          让我们从头开始:

          您可能已经知道递归函数是一种调用自身的函数。如果每次一个函数运行它都会调用它自己,你最终会陷入一个无限循环。因此,务必始终确保您的函数也知道何时停止调用自身。

          我们怎样才能做到这一点?函数的主体不会在调用之间改变,因为它是在编译时设置的。然而,将改变的是函数的输入。每当您编写递归函数时,您都需要包含在满足特定条件时避免递归调用的逻辑。

          在您的示例中,函数的输入是一个字符串数组。知道何时停止进行递归调用的一种方法可能是每次将较小的数组传递给函数,并在您有一个空数组时停止。这在像 C 这样的语言中会更好地工作,其中数组作为指针公开,但在 Java 中效率低下,因为您每次都必须创建一个新数组。

          一个更好的解决方案是保持一个索引指向您在列表中的当前位置(这就是为什么您需要一个辅助函数 - 添加额外的参数)。在每次调用时,您可以简单地在当前索引处打印字符串并增加索引。当索引不再在数组中时,你就完成了!

          如果您真的想很好地理解递归,我建议您学习一门函数式语言,例如 Lisp、Haskell 或 ML。函数式语言避免了可变状态(更改变量的值),因此它们不使用 for 循环之类的东西(因为需要在每次迭代时更新循环计数器)。所以他们使用递归来实现循环!例如,在 Java 中我们可能有:

          for (int i = 0; i < 10; i++) {
            System.out.println("Loop index: " + i);
          }
          

          而在 OCaml 中,我们将编写以下代码:

          let times = 10 in
          let rec loop count =
            if count = times then
              printf "Loop index: %d" count ;
              loop (count + 1)
          ;;
          

          这里的重要区别在于,我们每次都将一个新值传递给loop函数,而不是改变count的值(实际上不可能在上面的OCaml代码中)。

          【讨论】:

            【解决方案7】:

            我认为这不是什么好方法,尽管它会有所帮助。

            static void traverse(int []x)
            {
                if(x.length == 0)
                    return;
            
                traverse( Arrays.copyOf(x,x.length- 1));
            
                System.out.println(x[x.length-1]);
            
            }
            

            【讨论】:

              猜你喜欢
              • 2011-02-11
              • 2016-01-22
              • 2012-10-20
              • 1970-01-01
              • 1970-01-01
              • 2019-07-10
              • 2018-02-04
              • 2018-06-12
              • 2015-07-13
              相关资源
              最近更新 更多