2012-04-05 18 views
1

再帰処理の文字列(つまりchar array)を実行しています。 recursion treeでは、childにある文字列の長さが1未満です。parentです。同じ高さのすべての子は、同じ長さの文字列ですが、異なる文字を持ちます。新しいstringの長さが古い文字列の長さ以上になるたびに再帰を停止したいのですが、再帰と再帰の間にこの条件を挿入できません。 System.exit(0)を使用すると、完全なプログラムが終了します。以下は私のコードsnippet-私は3行目でSystem.out.println("length=" + len);を入れて実際に特定の条件で再帰を停止できません

private static void getMinLen(char[] oldStr) { 
    int len = oldStr.length; 

    /* 
    * This terminates the whole program, using break in place of 
    * System.exit(0) is not effective 
    */ 
    if (len < 2) 
     System.exit(0); 

    char[] newStr = new char[len - 1]; 

    for (int i = 0; i < len - 1; i++) { 
     /* 
     * Every character is matched with its next character and a new char 
     * array is created having length (len-1) 
     */ 
     getMinLen(newStr); 
    } 
} 

。最初に、長さは降順に印刷されますが、長さは増加し、再帰のために減少します。私は、コンソールがfollowing-

私は単に新しい長さが古いの長さ以上になる時はいつでも私の再帰を停止したい
length=6 
length=5 
length=4 
length=3 
length=2 
length=1 
length=3 
length=3 
length=2 
length=1 
length=4 
length=3 
length=2 
length=1 

を示し意味します。

+7

あなたは増分変数を使わずに 'for'ループを使っていますか?ちょうど同じ引数でメソッド 'getMinLen'を実行するだけですか? –

+1

しかし、あなたのメソッドには正確に何をしたいですか?入力が 'new char [] {'h'、 'e'、 'l'、 'l'、 'o'}'なら出力はどうなるでしょうか? – adarshr

+0

あなたのループは、一連の増加する引数で 'getMinLen'を呼び出します。これはアウトプットのダウン・アップ・パターンを説明する。それは、再帰関数からの破棄または復帰とは何の関係もありません。反復的なループで再帰的なロジックを複製しています。 –

答えて

0

ちょうどあなたがあなたがreturnを使用する必要があり、あなたの方法

+1

範囲が減少した後でも彼は "増加"します。 – amit

0

を終了したい行でreturn;System.exit(0);を交換してください。

if (len < 2) 
    return; 
+1

範囲が減少した後でも彼は "増加"します。 – amit

+1

'len <2'なら、再帰的ループは入りません。 –

+0

@adarshr:私は 'return'も使用しました。それでも私はその欺瞞をコントロールすることができません。私の質問では、コンソール出力も(デバッグのためだけに)置いています。最初に 'length'が1になったとき、私はそこで再帰を止めるだけです。その後、新しい「長さ」は古い「長さ」より大きくなります。古い「長さ」をどのようにして新しい「長さ」と比較できるのでしょうか? –

0

breakは、ループまたはスイッチ文を「中断」するだけであることに注意してください。メソッドを終了するには、return文またはメソッドの最後に到達する必要があります(戻り値の型がvoidの場合は暗黙のreturn文として機能します)。

は初期長さが4であると仮定します:それぞれの長さを印刷するとき

1. create a new array of length 3 (4-1) 
2. call the method recursively 3 times with an array of length 3 
3. each new call creates an array of length 2 (3-1) 
4. call the method recursively again, now 2 times and with an array of length 2 
5. each new call creates an array of length 1 (2-1) 
6. call the method recursively again, now once and with an array of length 1 
7. each new call creates an array of length 0 (1-1) 
8. those methods won't enter the loop since the condition now is `i < 0`, which is false with `i = 0` 

このように、私は次の出力

4 //initial call 
3 //first iteration of step 2 
2 //first iteration of step 4 
1 //only iteration of step 6 
2 //second iteration of step 4 
1 
3 //second iteration of step 2 
2 
1 
2 
1 
3 //third iteration of step 2 
2 
1 
2 
1 
を期待するあなたの方法は、以下のないことを

注意

ループを1回だけ繰り返して停止する必要がある場合、なぜそこにループを入れましたか?

+0

私が達成しようとしているのは、 'for'ループを使ってchar配列の次の文字で文字をチェックしていることです。その後、同じ 'for'ループ内に新しいchar配列が作成されます(私はここでそのコードを書き留めていません)。この新しく作成されたchar配列は、異なる文字を含む長さ 'n-1'を持ちます。今度は、この配列で 'getMinLen'メソッドが呼び出されます。 –

1

停止条件が満たされないgetMinLen(oldStr)へのすべての呼び出しで、に要素があることを実際に何度も呼び出すと、getMinLen(newStr)が呼び出されます。あなたの質問や最初のコメントから、これが意図的であるかどうかは不明です。 (newStrにループと同じ要素が複数ある場合は反復があることが示唆される場合があります)。

これは意図的なものではない場合、再帰呼び出しを1行下に移動する、つまりループの}の後ろに移動します。

意図的な場合は、再帰がどのように機能するか理解していない可能性があります。停止条件がどこかで実行されたという事実は、全体的には記録されず、停止条件が満たされた単一の呼び出しにのみ関連します。この点は、非常に短い文字列で始まらない限り、ループgetMinLenforという再帰呼び出しによって到達され、forループは、それ以降のすべての呼び出しをgetMinLenに実行し続けます。それを止めるには、グローバルブール変数が役立ちますが、非常に面白くありません。あるいは、関数がブール値を返すようにして、前の呼び出しがtrueを返したかどうかを各再帰呼び出しの前にチェックすることができます。しかし、再帰的アプローチが本当に問題に最も適しているかどうか再考することもできます。

関連する問題