2017-03-28 16 views
1

Javaの再帰に問題があります。問題は次のようなものです。Java再帰関数で配列をトレースする際の問題

n組のかっこを指定すると、整形されたかっこのすべての組み合わせを生成する関数を作成します。例えば、n = 3所与、解集合は

ある:

上記の問題のコードは再帰的であり、以下に記載されているとおり

public List<String> generateParenthesis(int n) { 
    ArrayList<String> result = new ArrayList<String>(); 
    dfs(result, "", n, n); 
    return result; 
} 

public void dfs(ArrayList<String> result, String s, int left, int right){ 
    if(left > right) 
     return; 

    if(left==0&&right==0){ 
     result.add(s); 
     return; 
    } 

    if(left>0){ 
     dfs(result, s+"(", left-1, right); 
    } 

    if(right>0){ 
     dfs(result, s+")", left, right-1); 
    } 
} 

Iの点で最大のプログラムをトレースすることができました私はそれを完全に辿ることができません。

場合、N = 2

left=2;right=2; 
result="(())", 
__________ 
| s="" | 
| l=2 | 
| r=2 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s=( | 
| l 1 | 
| r 2 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s=(( | 
| l 0 | 
| r 2 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s=(() | 
| l 0 | 
| r 1 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s= (())| 
| l=0 | 
| r=0 | 
|  | 
|  | 
|________| 

どのようになり、私が上記したものの後にプログラムの仕事?誰かがそれをトレースするのを助けることができますか?ありがとう。

+0

するとあなたは** **再帰を使用する必要がありますか? – Gooz

+0

私はあなたが "** tracing **"の意味を理解していません - "誰かが私を助けることができますか?"、 "プログラムをトレースできるかどうか"など。トレース/トレースは通常_debugging_を意味します。デバッグについて話しているようではありません。 –

+0

良い質問..この時点で再帰を学習していますが、他の問題を解決している間も同様の疑問がありました。ここで何が起こっているのかを知ることはいい考えです。ありがとう –

答えて

1

あなたが中断したところから:

__________ 
| s=( | 
| l=1 | 
| r=2 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s=() | 
| l 1 | 
| r 1 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s=()( | 
| l 0 | 
| r 1 | 
|  | 
|  | 
|________| 
    | 
    V 
__________ 
| s=()() | 
| l 0 | 
| r 0 | 
|  | 
|  | 
|________| 

を使用すると、Eclipseや他のIDEを使用している場合、ブレークポイントを設定し、あなたのプログラムは行ずつ実行方法を通過するのは簡単でなければなりません(すべてあなたを示します変数とそれらがどのように変化するか)。あなたがまだデバッグを学んでいないなら、私はあなたにそれをgoogleし、プログラムをデバッグする方法を学ぶことをお勧めします。

何あなたのプログラムを実際にやっている:

left (l=1, r=2) 
    left (l=0, r=2) 
    right (l=0, r=1) 
     right (l=0, r=0) 
     add result to s (l=0, r=0) 
    *here you break out of 3 recursive functions and values of l,r reset to (l=1, r=2)* 
    right (l=1, r=1) 
    left (l=0, r=1) 
     right (l=0, r=0) 
     add result to s (l=0, r=0) 
+1

あなたの投稿に私はあなたの投稿にコメントできません: 前回の再帰呼び出しから抜け出すと、その再帰的な呼び出しで既にleftを呼び出したためです。 (左 - >右 - >右)の代わりに(右 - >左 - >右)行くように呼び出します – DeepFriedPotater

+0

素晴らしい...あなたの説明のために多くのありがとう。感謝します。 –