2017-10-30 23 views
-3

このコードはなぜ機能しますか?このコードはどのように機能しますか? (Java再帰)

public static String reverse(String a) { 
     if(a.length() == 0) { 
      return a; 
     } else { 
      return reverse(a.substring(1)) + a.charAt(0); 
     } 
    } 

これも

public static String reverse(String a) { 
      if(a.length() == 0) { 
       return a; 
      } else { 
       return reverse(a.substring(1)) + a.substring(0); 
      } 
     } 

を?:ていません、ケース1での再帰の仕事をどうするか、何がa.charAt(0)が行う追加しますか?そして、この方法はどのようにベースケースに達しますか?

+7

**ドキュメントを読んで**、(HTTPS [ ''ストリング(INTたbeginIndex)]のJavadocをIE: //docs.oracle.com/javase/8/docs/api/java/lang/String.html#substring-int-):*この文字列の部分文字列である文字列を戻します。部分文字列は、指定されたインデックスの文字で始まり、**はこの文字列の末尾まで拡張されます**。*。 – Andreas

+2

また、何が起こるかを見るために**デバッグ**を試してみることもできます。それは非常に迅速にあなたに理由を示しています。 [デバッガとは何ですか?また、どのように問題を診断するのに役立ちますか?](https://stackoverflow.com/q/25385173/5221149) – Andreas

+0

コンピュータを鉛筆で紙を使って最も効果的に再帰させる方法です。 –

答えて

5

a.charAt(0)は最初の文字を返しますが、a.substring(0)0から全体Stringを返します。

return reverse(a.substring(1)) + a.substring(0, 1); 

のようなものに

return reverse(a.substring(1)) + a.substring(0); 

を変更し、期待どおりに動作します。

0

再帰的コードについての理解を深めるために、各メソッド呼び出しの状態を表示することができます。

public static String reverse(String a) { 
    System.out.println("Calling reverse(\"" + a + "\")"); 
    if(a.length() == 0) { 
     System.out.println("Base case encountered for string : \"" + a + "\""); 
     return a; 
    } else { 
     String b = reverse(a.substring(1)); 
     String c = a.charAt(0); 
     System.out.println(reverse(\"" + a + "\") returning \"" + b + "\" + \"" + c + "\""); 
     return b + c; 
    } 
} 

あなたがreverse("xyz")を呼び出すしようとすると、あなたは、標準出力の中に印刷された以下のテキストを見ることができます:

Calling reverse("xyz") 
Calling reverse("yz") 
Calling reverse("z") 
Calling reverse("") 
Base case encountered for string : "" 
reverse("z") returning "" + "z" = "z" 
reverse("yz") returning "z" + "y" = "zy" 
reverse("xyz") returning "zy" + "x" = "zyx" 

我々はいくつかの物事を見ることができます。

  • あなたは再帰的に文字列を減らします文字列が空である(長さがゼロである)ベースケースに達するまで。
  • ノンベースのケースでは、文字列を2つのセグメント、つまりbcに分割します。その後、あなたはreverse(b) + cを返します。
0

最初に 'a.substring()'はパラメータとして与えられたインデックスから始まる部分文字列を返します。したがって、再帰的メソッドのパラメータとして 'a.substring(1)'を使用すると、最初の文字は常にスキップされますパラメータとして与えられた文字列の長さは徐々に減少します。キャラクタが残っていなければ、ベースケースに到達します。

第2に、 'a.charAt()'は、パラメータとして指定された文字列のインデックスに存在する文字を返します。したがって、 'a.charAt(0)'は、再帰的メソッドのパラメータとして指定された文字列 'a'の最初のインデックスを返します。

最後に、最初のコードは、最初の文字以外の文字列全体を送信するたびに、逆の文字列の最後に最初の文字が含まれるために機能します。だから最後に、文字列全体が逆になります。 一方、第2コードは、最初の文字の代わりにパラメータとして与えられた文字列の最初のインデックスから始まる部分文字列全体を含みます。

あなたが最初のコードのような使用「のcharAt(0)」のいずれかすることができ、コードの動作させるために -

return reverse(a.substring(1)) + a.charAt(0); 

か、「を使用することができます。ストリング(0、1)」サブとして最初の文字だけを考慮して、それを返す -

return reverse(a.substring(1)) + a.substring(0, 1); 
関連する問題