- ベストアンサー
JavaScriptで順列生成アルゴリズムを実装する方法とは?
- 順列生成アルゴリズムを理解するためにJavaScriptを用いたプログラムを書き直しました。しかし、再帰処理の部分で理解できないスタックの流れになってしまいました。
- プログラムの実行フローを確認するため、再帰処理の各ステップでconsole.logを使用しました。
- 再帰後の処理(3)が連続して呼ばれる理由について理解ができません。プログラムが最後まで実行される理由を教えてください。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
「再帰呼び出し」そのものについて、理解できていますか? ・まったく別の関数を呼び出しているつもりになる ・機能だけで考える というあたりがコツだと思ってます。 ループ同じように同じ行を行ったり来たり、と考えていると理解できません。 function partition_0() { for ( var i = 0; i < N; i++ ) { // (1)対象の配列から数字を一つ取り出して、他の数字と入れかえる Swap(i,0) // (2)呼び出し permutation_1(); // (3)入れ替えた数字を元に戻す Swap(i,0) } function partition_1() { for ( var i = 1; i < N; i++ ) { // (1')対象の配列から数字を一つ取り出して、他の数字と入れかえる Swap(i,1) // (2')呼び出し permutation_2(); // (3')入れ替えた数字を元に戻す Swap(i,1) } と考えます すると、(2)で呼び出された partition_1 で(3')を実行したあと、戻ってきたpartition_0の(3)が実行される、ということがわかるかと思います。 同じ「関数」で連続実行されているわけではありません。 「別の関数」でたまたま同じような動きがあったために、連続実行しているように見えるだけです。 順列になる理由ですが a0,a1,...,aN の順列は次のようにして求められます。 (1)N=0 なら a0 の一通りだけです。 (2)N>0 なら a0 + (a0以外の順列) a1 + (a1以外の順列) ... aN + (aN以外の順列) となります。ここで、(a0以外の順列)、(a1以外の順列) .. を求めるのに、今示した「順列の求め方」を使います。
その他の回答 (1)
- Tasuke22
- ベストアンサー率33% (1799/5383)
それは連続して呼ばれているのではなく、 連続して帰っているのです。 呼ばれた分、帰らなくてはなりませんから。
お礼
「再帰呼び出し」と書くとつい呼び出し側を注視してしまって、繰り返し処理のように捉えてしまいます。 「再帰」ということはどういうことか、もう一度良く考えてみようと思います。 ありがとうございました。
お礼
ありがとうございました。 > まったく別の関数を呼び出しているつもりになる は、盲点でした! 自分の中で、再帰呼び出しと繰り返し処理を同じ次元で捉えていました。 仰るとおり、別の関数として呼び出していると捉えますとログの通りの処理になりました!! 3日悩んでいたので、とてもスッキリしました。 今度からは、kmeeさんから教わった考え方で、再帰呼び出しを使っていこうと思います。 本当にありがとうございました!!!