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か?

デバッグしたところ、例外をスローした後、再び再帰し、すべてのアスタリスクが「」に切り刻まれることに気付きました。何度も試しました。IllegalArgumentExceptionifをスローする必要もありますn < 0

4

2 に答える 2

6

Java では文字列は不変であるため、新しい値を割り当てる必要があります(そしてパラメーターとして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(不変の文字列インスタンスが何度も何度も作成されるため)。その場合は、次を使用することをお勧めしますStringBuilder

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

私のマシンでは、文字列連結を使用するループ バージョンでは、n = 100000 の場合に約 12 秒かかりますが、StringBuilderバージョンでは 0.007 秒かかります。

于 2012-05-10T19:20:37.210 に答える
4

あなたのコードはすべての再帰を呼び出し、 local を保存し、tempthis を返し、決して使用されません。

于 2012-05-10T19:20:57.537 に答える