【问题标题】:Require assistance with String recursion in JavaJava 中的字符串递归需要帮助
【发布时间】:2023-06-26 18:41:01
【问题描述】:

我现在只是在学习如何使用递归,我在理解以下代码的工作原理时遇到了一些麻烦:

    public static String reverseString(String str)
    {
        if (str.length() == 0)
             return str;
        else
            return reverseString(str.substring(1)) + str.charAt(0);
    }

我的程序的目标是编写一个递归方法,它将接受一个字符串作为参数并返回该字符串的相反形式。我也知道这段代码可以工作。

我只是有点困惑它为什么起作用。我希望有人了解递归并知道如何解释它!我了解子字符串的工作原理以及该方法如何将第一个字母与单词分开(例如 Mike ---> ike + M)。

我不明白的是,基本情况如何达到零,以及该方法如何以相反的顺序返回字符串,而不是无限地进行。

任何帮助将不胜感激!

【问题讨论】:

  • 添加日志并使用逐步调试器查看函数的进出
  • 尝试单步执行。每次递归调用的输入会发生什么变化?
  • 附带说明,if (str.length() == 0) 可以是 if (str.length() == 1)

标签: java string recursion methods substring


【解决方案1】:

str.substring(1) 将返回原始的子字符串,从第一个索引开始到字符串的末尾。所以,例如:

"test".substring(1).equals("est") == true

所以每次递归调用,传入的字符串都会短一个字符,最终满足0长度字符串的终止条件。

您显示的代码基本上只是将给定字符串的第一个字符附加到字符串其余部分的末尾(倒数第二个字符)。

对于递归问题,请尝试使用显式参数值写出调用堆栈。一旦到达堆栈的最终调用,您将达到终止条件,并且返回的结果将“冒泡”备份调用堆栈。

【讨论】:

    【解决方案2】:

    让我们逐行评估:

    1. reverseString(str.substring(1)) + str.charAt(0) // ______ + M
    2. reverseString(str.substring(1)) + str.charAt(0) // ______ + i + M
    3. reverseString(str.substring(1)) + str.charAt(0) // ______ + k + i + M
    4. reverseString(str.substring(1)) + str.charAt(0) //      e + k + i + M 
    

    【讨论】:

      【解决方案3】:

      每次使用较短的字符串调用该方法时:删除第一个字符并随后添加。

      呼叫将按如下方式进行(例如"Mike"):

      reverseString("Mike")
      reverseString("ike") + 'M'
      (reverseString("ke") + 'i') + 'M'
      ((reverseString("e") + 'k') + 'i') + 'M'
      (((reverseString("") + 'e') + 'k') + 'i') + 'M'
      ((("" + 'e') + 'k') + 'i') + 'M' // base case is reduced: length is zero, therefore reverseString returns ""
      (("e" + 'k') + 'i') + 'M'
      ("ek" + 'i') + 'M'
      "eki" + 'M'
      "ekiM"
      

      在第一次迭代中,字符串的长度为 4。每次执行reverseString 时,长度都会减小,因此会在调用一定次数后结束。

      【讨论】: