简体   繁体   English

递归isPalindrome函数如何工作?

[英]How does recursive isPalindrome function work?

I'm working on some introductory recursion problems and I have a clarifying question I'd like to get answered. 我正在研究一些介绍性的递归问题,我有一个澄清的问题,我想得到答案。 The most nagging question I have is how is this recursion operating in the solved problem below? 我遇到的最棘手的问题是这个递归是如何在下面解决的问题中运行的?

Despite having solved the problem, I'm just not understanding how the recursion call makes its way into the interior of the string. 尽管已经解决了这个问题,但我只是不理解递归调用如何进入字符串的内部。 It would seem, from just looking at the code, that this method would only ever check the two characters on either end of the given string, without checking the rest. 从查看代码看,这个方法似乎只检查给定字符串两端的两个字符,而不检查其余字符。 My textbook gives the deeply unsatisfying answer of, basically, don't worry about how recursion works as long as your return statement refines the problem. 我的教科书给出了非常不满意的答案,基本上,只要你的return语句改进了问题,就不要担心递归是如何工作的。 But I'm having difficulty knowing how to approach subsequent recursion problems without understanding how one can trace a recursive method in the same way one would trace a loop. 但是我很难知道如何处理后续的递归问题而不了解如何跟踪递归方法的方式与跟踪循环的方式相同。

Any words of wisdom would be much appreciated. 任何智慧的话都会受到赞赏。

Thanks! 谢谢!

public class isPalindrome {

public static boolean isPalindrome(String str)
{
    //test for end of recursion
    if(str.length() < 2) {return true;}

    //check first and last character for equality
    if(str.charAt(0) != str.charAt(str.length() - 1)){return false;}

    //recursion call 
    return isPalindrome(str.substring(1, str.length() - 1));
}
public static void main(String[] args)
{
    System.out.print(isPalindrome("deed"));
}
}

The isPalindrome() function is recursively being called on str.substring(1, str.length() -1). 在str.substring(1,str.length() - 1)上递归调用isPalindrome()函数。 So the callstack would look like this for the isPalindrome() calls: 所以对于isPalindrome()调用,callstack看起来像这样:

1. isPalindrome("abcddcba"): 

   ("a" == "a") = true, so recurse

2. isPalindrome("bcddcb"):

   ("b" == "b") = true, so recurse

3. isPalindrome("cddc"):     

   ("c" == "c") = true, so recurse

4. isPalindrome("dd"): 

   ("d" == "d") = true, so recurse  

6. isPalindrome(""):           

   length < 2, so return true

The return value of the last call will propagate all the way to the top. 最后一次调用的返回值将一直传播到顶部。

With recursion, pictures always help. 随着递归,图片总是有帮助。 Do your best to draw out the callstack as a diagram. 尽力将callstack绘制成图表。 It'll allow you to visualize, and therefore better understand, more complex recursions. 它将允许您可视化,因此更好地理解更复杂的递归。 This is a simple "linear" recursion but you'll eventually face "tree" like recursions. 这是一个简单的“线性”递归,但你最终会像递归一样面对“树”。

Here's a picture that illustrates this exact problem for you to better visualize: 这是一张图片,说明了这个确切的问题,以便您更好地可视化:

回文递归

Think of the palindrome: 想想回文:

risetovotesir

This can actually be built by starting with the palindrome v (a one-character string is always a palindrome, as is an empty string) and adding the same letter to front and back: 这实际上可以通过从回文v开始构建(一个字符的字符串总是回文,就像一个空字符串)并在前后添加相同的字母:

      v           Start with palindrome 'v'.
     ovo          Add 'o' to both ends.
    tovot         Then 't'.
   etovote        Then 'e'.
  setovotes       Then 's'.
 isetovotesi      Then 'i'.
risetovotesir     And finally 'r'.

The process used by that recursive function is in the opposite direction, breaking the string down bit by bit. 该递归函数使用的过程是相反的方向,逐位打破字符串。 It detects if it is indeed a palindrome is if both: 如果两者都检测到它是否确实是回文:

  • the first and last characters are equal; 第一个和最后一个字符相等; and
  • the inside of the string (once those two are removed) is a palindrome. 字符串的内部(一旦这两个被删除)是回文。

Hence the code can be written as: 因此代码可以写成:

public static boolean isPalindrome (String str) {
    // Zero- or one-character string is a palindrome.

    if (str.length() < 2)
        return true;

    // If first and last characters are different, it's NOT palindromic.

    if (str.charAt (0) != str.charAt (str.length() - 1))
        return false;

    // Otherwise it's palindromic only if the inner string is palindromic.

    return isPalindrome (str.substring (1, str.length () - 1));
}

Using a string of peed deep , the different levels are: 使用一串peed deeppeed deep ,不同的级别是:

1. length 9 >= 2, both ends are 'p', next level checks 'eed dee'.
2. length 7 >= 2, both ends are 'e', next level checks 'ed de'.
3. length 5 >= 2, both ends are 'e', next level checks 'd d'.
4. length 3 >= 2, both ends are 'd', next level checks ' ' (space).
5. length 1 <  2, return true.

Alternatively, a non-palindrome (although tantalisingly close) of star rots gives you: 或者, star rots的非回文(虽然诱人地接近)给你:

1. length 9 >= 2, both ends are 's', next level checks 'tar rot'.
2. length 7 >= 2, both ends are 't', next level checks 'ar ro'.
3. length 5 >= 2, ends are 'a' and 'o', so return false.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM