2012-05-10 38 views
2
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更大的值称为可有人请解释一下吗?Java的递归返回一个字符串

我调试并注意到,抛出异常后,它再次递归,所有的星号被砍成“”。我已经尝试了很多次。它还要求你应该抛出IllegalArgumentException如果n < 0

+0

为什么这个问题被低估?这可能会更好,但是,这是一个仍然学习用Java编码的人的合法问题。 – pcalcao

+0

不要对预期条件使用异常;异常意味着用于特殊的发生,而不是递归完成的信号。 –

+0

这个例外甚至意味着什么?你把它扔在一个“试块”中,因此它会立即被捕获。 – Thomas

回答

6

在Java中的字符串是immuntable,因此你需要分配一个新的价值temp(并通过temp作为参数):

temp = starString(n-1, temp);   

另外你需要分配给strtemp,否则每次递归将只返回一个星号:

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值(由于不断重复创建不可变字符串实例)而迅速变慢。使用字符串连接需要大约12秒ñ= 100000,而StringBuilder版本需要0.007秒

private String starString(int n){   
    StringBuilder s = new StringBuilder(); 
    for(int i = 0; i <= n; i++) { 
    s.append("*"); 
    } 
    return s.toString(); 
} 

在我的机器循环的版本:在这种情况下,你最好使用StringBuilder

+0

谢谢......但我通过递归季度。所以循环迭代是不可能的。 – ac3hole

4

你的代码调用每一次递归,存储一个本地temp,返回这个,它永远不会被使用。