我正在通过练习18.10第10版Java编程简介(综合版),内容如下:
编写一个递归方法,使用以下方法标题查找字符串中指定字母的出现次数:
public static int count(String str,char a)
所以这是我对该方法的实现:
public static int count(String str, char a)
{
if (str.charAt(str.length() - 1) != a)
return 0;
else
return 1 + count(str.substring(0, str.length()), a);
}
我的基本案例检查最后一个字符是否是指定的“重复出现的字符”;如果不是,则在字符串中出现字符的“count”次数加1,并递归调用count方法。
使用此实现运行程序会导致StackOverflowError。我猜这可能是由于无限递归,而且这是导致问题的代码:
str.substring(0, str.length())
麻烦的是,我不完全确定我理解为什么。 substring(int beginIndex,int endIndex)方法的描述读取
返回一个字符串,该字符串是此字符串的子字符串。子字符串从指定的beginIndex开始,并扩展到索引endIndex - 1处的字符。
所以我编写它的方式,它应该返回一个子字符串,其中包含除最后一个字符之外的原始字符串中的每个字符,因此通过递归一次删除字符串的一个字符。
我可以看到为什么可能存在这个问题,因为当字符串的长度为1或0时,没有什么可以告诉递归停止,但是因为问题是StackOverflowError而不是IndexOutOfBounds异常,所以我'有点迷路..
答案 0 :(得分:2)
您应该使用[string - the_last_character]
调用该方法(递归),因为已经检查并计算了最后一个字符。
此外,您必须检查字符串是否为空以停止递归。
试试这个:
public static int count(String str, char a)
{
if(str.length() == 0) // here we have to stop the recursion as the string is empty!
return 0;
if (str.charAt(str.length() - 1) != a)
return count(str.substring(0, str.length() - 1), a); // here we send the string - the last character which has been already checked.
else
return 1 + count(str.substring(0, str.length() - 1), a);
}
答案 1 :(得分:1)
return 1 + count(str.substring(0, str.length()), a)
这就是问题所在。你正在使用整个字符串进行递归调用。因此该函数不断重复,检查相同的字符。相反,返回一个子字符串:
return 1 + count(str.substring(0, str.length() - 1), a)
您还需要在str.length() == 0
时添加基本案例。
答案 2 :(得分:0)
方法str.length()
不返回字符串中最后一个字符的索引;它返回字符串的长度。考虑字符串" A" - 最后一个字符的索引为0(零),但str.length()
返回1.
所以当前str.substring(0, str.length())
返回一个等于整个字符串str
的字符串。
相反,您想要更改代码,以便子字符串的第二个参数变为小于字符串长度的一个字符,因此结果将比原始字符短一个字符:
return 1 + count(str.substring(0, str.length() - 1), a);