public String starString(int n){
int m = (int)Math.pow(2,n);
String str="";
str = starString(m-1,str);
return str;
}
private String starString(int n, String str){
String temp ="";
if (n<0) {
try{
throw new IllegalArgumentException();
}
catch(IllegalArgumentException ex){
}
}
else {
temp+=("*");
starString(n-1,str);
}
return temp;
}
有人可以向我解释为什么这段代码会返回一个星号,即使它被一个大于n >= 0
的值调用了吗?
我调试并注意到在抛出异常之后它再次递归并且所有的星号都被切成了“”。我已经尝试过很多次了。它还要求你应该IllegalArgumentException
n < 0
。{/ p>
答案 0 :(得分:6)
在Java字符串中是不可分割的,因此您需要为temp
分配一个新值(并将temp
作为参数传递):
temp = starString(n-1, temp);
此外,您需要将str
分配给temp
,否则每次递归都会返回一个星号:
String temp = str;
递归方法的更简单,更清晰(更正确)的版本如下所示:
private String starString(int n){
String temp = "*";
//only recurse as long as n > 0, i.e. the last invocation would be made with n = 0
if (n > 0){
temp += starString(n-1);
}
return temp;
}
请注意,您甚至不需要将字符串作为参数传递。还要注意,递归在这里是过度的,使用循环会产生很多错误。另请注意,字符串连接成本很高,并且对于n
的较高值而言速度很慢(由于不可变的字符串实例一次又一次地创建)。在这种情况下,您最好使用StringBuilder
:
private String starString(int n){
StringBuilder s = new StringBuilder();
for( int i = 0; i <= n; i++ ) {
s.append("*");
}
return s.toString();
}
在我的机器上,使用字符串连接的循环版本大约需要12秒,n = 100000,而StringBuilder
版本需要0.007秒。
答案 1 :(得分:4)
您的代码调用每次递归,存储本地temp
,返回此内容并且永远不会使用它。