Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关于递归方法代码的问题_Java_String_Recursion_Substring - Fatal编程技术网

Java 关于递归方法代码的问题

Java 关于递归方法代码的问题,java,string,recursion,substring,Java,String,Recursion,Substring,我对这个代码有一些问题 public static String reverseString( String s ) { if ( s.length() == 0 ) return ""; String firstChar = s.substring( 0, 1 ); String reverseRest = reverseString( s.substring( 1 ) ); String result = reverseRest + firstChar; r

我对这个代码有一些问题

public static String reverseString( String s )
{
  if ( s.length() == 0 )
    return "";

  String firstChar = s.substring( 0, 1 );
  String reverseRest = reverseString( s.substring( 1 ) );

  String result = reverseRest + firstChar;

  return result;
}

public static void main( String[] args ) 
{
  String a = "The sky's the limit!";
  System.out.println( reverseString( a ) );
}
问题1:终止情况究竟如何运作?s.length将如何等于0

问题2:为什么代码需要“firstChar”才能反转字符串?当reverseString接受子字符串0且不必添加第一个字符时,为什么代码不起作用

问题1:终止情况究竟如何运作?怎么 s.length是否永远等于0

如果您阅读,那么您将理解它返回的子字符串以指定的字符开始,并一直延伸到结尾。由于您指定起始字符1,并且字符以0开始编号,
子字符串(1)
本质上意味着“以第二个字符开始”。这样,嵌套调用的字符串长度正好减少一个字符。当然,它最终会达到0!当从长度为1的字符串中获取子字符串(1)时,它将达到0,因为对于这样的字符串,“从第二个字符开始”意味着一个空子字符串

问题2:为什么代码需要“firstChar”才能 把绳子倒过来?为什么反向限制时代码不起作用 接受0的子字符串,并且不必添加第一个字符

这就是递归的意义所在。如果取第一个字符,反转字符串的其余部分,然后将该字符附加到字符串的其余部分的末尾,如果不是反转字符串,会得到什么

或者,如果你想要严谨,这是一件光荣的事情,那么让我们用正确的方式来做。让我们首先证明这个函数正确地反转了长度为0的字符串

反转的空字符串就是空字符串本身。由于当输入字符串为空时,代码显式返回一个空字符串(顺便说一句,为了清楚起见,最好将
length()==0
替换为
isEmpty()
),这证明该函数适用于0长度字符串。那没那么难吧

现在让我们证明,如果该函数适用于长度为
i
i>=0
)的字符串,那么它也适用于长度为
i+1
的字符串。假设
s.length()==i+1
。我们取第一个字符,然后调用
反向字符串(s.substring(1))
。此调用的参数是长度为
i
的字符串,因为它比
s
短一个字符。因为我们假设我们的函数对于长度为
i
的字符串非常有效,所以结果是字符串的正确反转子字符串,从字符1(第二个)开始。然后,我们将
s
的第一个字符附加到此字符串,从而使长度
i+1
s
正确反转

我们已经证明它适用于长度
0
,因此从我们的第二个证明可以看出,它也适用于长度
1
。但从这一点来看,它也适用于长度
2
。等等,等等。。。这就是证明递归函数工作的方法

现在,如果不添加第一个字符,会发生什么。假设该函数对于较短的字符串(
子字符串(1)
)工作正常,那么最终得到的字符串将短一个字符。短一个字符的字符串显然不会与原始字符串相反,因此,如果只反转
子字符串(1)
,而不向结果添加任何内容,则证明此函数不可能工作

如果在递归调用中传递子字符串(0),会发生什么?这是另一个有趣的问题。在证明的第二部分中,我们假设该函数适用于较短的字符串。在这种情况下,
子字符串(0)
不是较短的字符串。事实上,它是原始字符串本身,因此传递
子字符串(0)
相当于只传递
s
。所以我们的证据不再有效了。此外,由于我们正在进行相同的调用,它将继续一次又一次地调用自己,直到递归变得太深时得到
StackOverflowerError

因此,整个想法是基于将手头的任务分解为更小的部分,而
子字符串(0)
不是更小的部分。另一个有趣的任务是将字符串分成两半,而不是仅仅切掉一个字符,然后返回
reverseString(右)+reverseString(左)
。我建议您尝试这样做(注意奇数/偶数长度),看看它是否有效,并证明它是如何工作的

问题1:终止情况究竟如何运作?怎么 s.length是否永远等于0

如果您阅读,那么您将理解它返回的子字符串以指定的字符开始,并一直延伸到结尾。由于您指定起始字符1,并且字符以0开始编号,
子字符串(1)
本质上意味着“以第二个字符开始”。这样,嵌套调用的字符串长度正好减少一个字符。当然,它最终会达到0!当从长度为1的字符串中获取子字符串(1)时,它将达到0,因为对于这样的字符串,“从第二个字符开始”意味着一个空子字符串

问题2:为什么代码需要“firstChar”才能 把绳子倒过来?为什么反向限制时代码不起作用 接受0的子字符串,并且不必添加第一个字符

这就是递归的意义所在。如果取第一个字符,反转字符串的其余部分,然后将该字符附加到字符串的其余部分的末尾,如果不是反转字符串,会得到什么

或者,如果你想要严谨,这是一件光荣的事情,那么让我们用正确的方式来做。让我们首先证明这个函数可以反转长度为0的字符串