java中递归函数中的字符串返回值

Posted

技术标签:

【中文标题】java中递归函数中的字符串返回值【英文标题】:String return value in recursive function in java 【发布时间】:2020-09-25 14:30:16 【问题描述】:

所以我目前正在练习 java,我是一个初学者,我尝试解释我编写的所有示例,以便我能够理解事情是如何以及为什么会这样。我理解递归的概念,但是当我试图解释这段代码时遇到了这个问题:

import java.util.Scanner;
public class JavaExample 

    public static void main(String[] args) 
        String str;
        System.out.println("Enter your username: ");
        Scanner scanner = new Scanner(System.in);
        str = scanner.nextLine();
        scanner.close();
        String reversed = reverseString(str);
        System.out.println("The reversed string is: " + reversed);
    

    public static String reverseString(String str)
    
        if (str.isEmpty())
            return str;
        //Calling Function Recursively
        return reverseString(str.substring(1)) + str.charAt(0);
    

以我目前对递归的了解,我试图这样解释它。 例如,让我们有一个字符串“Petar”:

reverseString(etar)+P
reverseString((tar)+etar)+P
reverseString((ar)+tar+etar)+P
reverseString((r)+ar+tar+etar)+P
-----------------------------------
r+ar+tar+etar+P

我注意到正确的答案是每个部分的第一个字符,所以我必须接近。

感谢您抽出宝贵时间,如果我没有清楚地表达自己,我很抱歉,我来自欧洲(英语不好)。

【问题讨论】:

【参考方案1】:

它是这样工作的:

reverseString("Peter") = 
        reverseString("eter") + P = 
                (reverseString("ter") + e) + P = 
                    ((reverseString("er") + t) + e) + P = 
                        (((reverseString("r") + e) + t) + e) + P = 
                            ((((reverseString("") + r) + e) + t) + e) + P =
                            (((("" + r) + e) + t) + e) + P =
                            ((((r) + e) + t) + e) + P =
                            (((r + e) + t) + e) + P = 
                            (((re) + t) + e) + P = 
                            ((re + t) + e) + P = 
                            ((ret) + e) + P = 
                            (ret + e) + P = 
                            (rete) + P = 
                            rete + P = 
                            reteP

【讨论】:

非常感谢您的详细回答。真的很感激时间和精力。现在一切都清楚了!【参考方案2】:

从最简单的例子开始应该很清楚:空字符串和大小为 1 的字符串。然后替换每个调用的参数,使其更明显:

// string.isEmpty() is true, so the empty string is returned immediately
reverse("")  -> "" 
reverse("a") -> reverse("") + 'a' -> ("") + 'a' -> "a"

这些是简单的例子,让我们用更长的字符串来试试吧:

reverse("ab")  -> reverse("b") + 'a'
reverse("abc") -> reverse("bc") + 'a'
               -> (reverse("c") + 'b') + 'a'
               -> ((reverse("") + 'c') + 'b') + 'a'
               -> ((("") + 'c') + 'b') + 'a'
               -> "cba"

一般模式现在应该很清楚了。为了完整起见,让我们手动“展开” 4 个字符串的递归调用:

reverse("abcd") -> reverse("bcd") + 'a'
                -> (reverse("cd") + 'b') + 'a'
                -> ((reverse("d") + 'c') + 'b') + 'a'
                -> (((reverse("") + 'd') + 'c') + 'b') + 'a'
                -> (((("") + 'd') + 'c') + 'b') + 'a'
                -> "dcba"

【讨论】:

哦,现在很清楚了。我错了,因为我认为该方法仅使用 str.substring(1) 部分进行自我调用,即 (reverseString(str.substring(1))) + str.charAt(0)。非常感谢您的回答! @PetarBrdaroski 它是。递归调用仅传递字符串的“尾部”。递归调用返回后追加头部【参考方案3】:

在您的示例中,当您的函数仅达到一个字符时 当它变成只有“P”时的彼得 并且你调用的字符串不为空

substring(1)

调用超出范围的索引,而字符串在索引 0 上只有 P 而在索引 1 上没有 您必须设置一个基本情况来检查字符串长度是否等于或小于 1

【讨论】:

【参考方案4】:

您第一个电话打对了,但其他电话有点不对劲。在每个递归调用中,您都返回以第一个字符结尾而不是开头的字符串。因此,递归看起来像这样:

reverseString("Petar")
return reverseString("etar") + "P"
return reverseString("tar") + "e"
return reverseString("ar") + "t"
return reverseString("r") + "a"
return reverseString("") + "r"
return ""

所以函数会返回:(((((("")+"r")+"a")+"t")+"e")+"P"),即"rateP"。

【讨论】:

非常感谢您的解释,感谢您的时间!【参考方案5】:

你在第一行做得很好reverseString(etar)+P你只在最后保留*第一个字符**,对下一行做同样的事情

将第一个字符放在末尾​​li> 将其余部分发送给方法
reverseString(etar)+P
reverseString(tar) +e+P
reverseString(ar)  +t+e+P
reverseString(r)   +a+t+e+P
reverseString('')  +r+a+t+e+P // stops when empty string is passed

【讨论】:

我认为它就像:(reverseString(str.substring(1))) + str.charAt(0),也就是我认为该方法仅调用 str.substring(1) .但是感谢您的回答,它有很大帮助!

以上是关于java中递归函数中的字符串返回值的主要内容,如果未能解决你的问题,请参考以下文章

递归 JavaScript 函数正在丢失返回值

终于搞明白了二叉树的递归函数是否需要返回值

在Java中的整数数组列表中找到最小值的递归函数

尾递归 递归函数中,递归调用是整个函数体中最后的语句,且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归,空间复杂度是O

如何退出方法,即如何从java中的递归函数返回?

JavaScript 函数进阶函数(匿名回调递归函数)及相关练习