java如何使用递归来反转字符串

时间:2014-07-18 14:47:32

标签: java recursion

这是一个递归方法:

public static String reverseRecursively(String str) {

    //base case to handle one char string and empty string
    if (str.length() < 2) {
        return str;
    }
    System.out.println(str.substring(1) + " "+  str.charAt(0));
    return reverseRecursively(str.substring(1)) + str.charAt(0);
}

显然它应该反转String。我从这个方法得到的输出是:

23456 1
3456 2
456 3
56 4
6 5
654321

工作正常。但问题是,我不明白 它是如何运作的。看完输出后,我完全糊涂了。我理解的是,它返回的是截断的String,它越来越短。有人可以解释一下这是如何起作用的吗?

4 个答案:

答案 0 :(得分:4)

详细说明:

首先从这个字符串开始:

"123456"

它首先达到了这个条件:

if (str.length() < 2) {
    return str;
}

String超过1个字符,因此在此处不执行任何操作。下一个执行的方法是:

System.out.println(str.substring(1) + " "+  str.charAt(0));

为简单起见,我们只关注内部部分:

str.substring(1) + " " +  str.charAt(0)

所以这里有两种方法substring(int)charAt(int)

  1. substring(int):此方法返回,因为名称暗示原始字符串的子字符串。它从您传递给方法的索引开始。
  2. charAt(int):这会返回String
  3. 中给定位置的字符

    现在,如果我们再次查看方法中的代码,请记住当前str是&#34; 123456&#34;。

    如果我们在此substring(1)上使用String,则会返回从索引1开始的所有内容,因此substring(1)会返回&#34; 23456&#34;。只剩下第一个字符了。

    如果我们使用charAt(0),我们会在String m中找到第一个字符,因此charAt(0)只返回&#34; 1&#34;。

    现在我们知道第一次迭代中这些方法返回的值是什么:

    str.substring(1) + " " +  str.charAt(0) = "23456 1"
         |                        |
         V                        V
      "23456"        + " " +     "1"        = "23456 1"
    

    然后递归开始:

    return reverseRecursively(str.substring(1)) + str.charAt(0);
    

    因此str.substring(1)的值现已传递到reverseRecursively()。这里的str.charAt(0)只会在String返回后附加到reverseRecursively()。换句话说,它看起来像这样:

    return reverseRecursively("23456") + "1";
    

    在下一次迭代中,一切都重新开始,唯一的区别是现在reverseRecursively()String&#34; 23456&#34;而不是&#34; 123456&#34;。所以最终会归结为:

    return reverseRecursively("3456") + "2" + "1";
    

    再次在下一次迭代中,它可以解决这个问题:

    return reverseRecursively("456") + "3" + "2" + "1";
    

    这种情况一直持续到String传入reverseRecursively()的长度小于2,所以一旦递归到达此值:

    reverseRecursively("6")
    

    if语句将启动并返回String "6"

    if (str.length() < 2) {
        return str;
    }
    

    所以最终结果将是:

    "6" + "5" + "4" + "3" + "2" + "1" = "654321"  
    

    摘要

      

    总结一下:

         

    这种方法的作用是从String获取所有内容   第一个字符和第一个字符添加到结尾   将String的其余部分再次传入后再String   reverseRecursively()再次导致第一个角色出现   附加到最后,其他一切都重新开始。整个东西   String达到1的长度后停止。

    所以这一切归结为:

                             "123456"  
                        "23456" + "1"  
                   "3456" + "2" + "1"  
              "456" + "3" + "2" + "1"  
         "56" + "4" + "3" + "2" + "1"  
    "6" + "5" + "4" + "3" + "2" + "1" = "654321"  
    

    我希望我能正确解释算法!如果您有任何其他问题,请随时询问!

答案 1 :(得分:1)

它的工作方式与递归函数的工作方式相同。它会递归调用,直到遇到终止条件:str.length() < 2在这种情况下。然后返回最后/最深的函数调用,然后调用函数调用也返回,并且其调用函数调用也返回,依此类推。然后你得到了结果。

答案 2 :(得分:1)

有几种方法可以使用递归来反转字符串,这个特殊的例子会在堆栈展开时生成反向字符串。

下图可能有所帮助,您在调用发生时打印出参数(被推入堆栈)。这是在它展开时发生的事情。在每一行我都用它的递归调用替换了对rev的调用,这是对rev和串联的另一个调用。直到字符串少于两个字符,此时它才会停止。

rev("1234")
rev("234") + "1"
(rev("34") + "2") + "1"
((rec("4") + "3") + "2") + "1"
(("4" + "3") + "2") + "1"

答案 3 :(得分:0)

这是一个反向打印字符串的方法。

public static void reverseRecursively(String str) {
    //Base case
    if (str.length() < 2) {
        System.out.println(str);
        return;
    }
    //Recursive Call the string without the first charecter
    reverseRecursively(str.substring(1));

    //print the first char of the string
    System.out.println(str.charat(0));
}

好的,这里发生的是当你调用函数时传递参数'str'。对于这个例子,我们可以说str的值是“Waffle”。由于我们的字符串太长,因此无法满足基本情况。下一行代码是递归调用。 “affle”传递给新功能。由于我们已经在函数内部,因此它的所有内存都被推送到“堆栈帧”。这会快照“str”的值并将其放在一边供以后使用。视觉表示:

“华夫饼” - &gt;传递给recursiveFunction      没有基本的符合      调用新的recursiveFunction      当New函数返回时,将保存堆栈帧      “affle” - &GT;传递给recursiveFunction           没有基础符合           调用新的recursiveFunction           推送另一个堆栈框架保存“affle”                   “ffle”被传递给新的递归函数

重复此过程,直到满足基本大小写。一旦调用了返回值('str'的值=“e”,我的函数在返回之前打印“e”),stackFrame弹出并且'str'的值返回到前一个值“le”。下一行是打印状态,打印出str的第一个字符,以便打印“l”。

重复此操作,直到所有帧都已完成运行。

导致看起来像这样的consol: Ë 升 F F 一个 瓦特