再帰 は、関数がそれ自体を呼び出す手法です。これは、より大きな問題を解決するために、その問題を小さな問題に分割するプログラミング パターンです。 JavaScript で再帰を使用すると、ループや反復などの処理を行うことができますが、一部の問題を解決するには、再帰を使用する方が簡単で透過的です。
再帰はどのように機能するのでしょうか?
再帰には 2 つの主要な部分があります:
-
基本ケース: これは、関数がそれ自体を呼び出さなくなる条件です。これは、再帰関数の停止点として機能します。基本ケースのない再帰関数は、スタック オーバーフロー (つまり、関数の繰り返し呼び出しによるメモリ不足) を引き起こす可能性があります。
-
再帰的なケース: これは関数がそれ自体を呼び出す部分であり、問題をより小さな部分に分割して解決しようとします。
例:
-
階乗計算: 階乗とは、ある数値から 1 までのすべての数値の積の合計です。例えば、n!=n×(n−1)×(n−2)×...×1 5! = 5 * 4 * 3 * 2 * 1 = 120.
階乗は、その数値から 1 までのすべての正の整数の積です。
function factorial(n) {
// Base case: n যদি 1 হয়, তাহলে 1 রিটার্ন করো
if (n === 1) {
return 1;
}
// Recursive case: n * factorial(n-1)
return n * factorial(n - 1);
}
console.log(factorial(5)); // Output: 120
ログイン後にコピー
ここで、階乗関数は n が 1 になるまで自分自身を呼び出しています。 n が 1 の場合、関数はそれ自体を呼び出さず、1 を返します。この結果は、以前の呼び出しを通じて徐々に返され、元の呼び出しは最終結果として 120 を返します。
factorial(5) が呼び出されると、まず 5 * fastial(4) が呼び出され、基本ケースの条件が満たされる fastial(0) まで続きます。
-
フィボナッチ数列: フィボナッチ数列は、各数値が前の 2 つの数値の合計である有名な例です。 F(n)=F(n−1)+F(n−2)
フィボナッチ数列は、最初の 2 つの数値が 0 と 1 であり、後続の各数値は前の 2 つの数値の合計である一連の数値です。例: 0、1、1、2、3、5、8、…
function fibonacci(n) {
// Base cases: n যদি 0 বা 1 হয়, সরাসরি n রিটার্ন করো
if (n === 0 || n === 1) {
return n;
}
// Recursive case: fibonacci(n-1) + fibonacci(n-2)
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.log(fibonacci(6)); // Output: 8
ログイン後にコピー
説明:
-
基本ケース: n の値が 0 の場合、fibonacci(0) は 0 を返します。 n の値が 1 の場合、fibonacci(1) は 1 を返します。
-
再帰的なケース: それ以外の場合、 fibonacci(n) は n−1 と n−2 で自分自身を呼び出し、それらの合計を返します。
答えの説明:
-
fibonacci(0) = 0
-
fibonacci(1) = 1
-
fibonacci(2) = fibonacci(1) + fibonacci(0) = 1 + 0 = 1
-
fibonacci(3) = fibonacci(2) + fibonacci(1) = 1 + 1 = 2
-
fibonacci(4) = fibonacci(3) + fibonacci(2) = 2 + 1 = 3
-
fibonacci(5) = fibonacci(4) + fibonacci(3) = 3 + 2 = 5
-
fibonacci(6) = fibonacci(5) + fibonacci(4) = 5 + 3 = 8
এভাবে fibonacci(6) এর মান দাঁড়ায় 8, যা 6-তম ফিবোনাচি সংখ্যা।
-
Tree Traversal: Tree ডেটা স্ট্রাকচারে একটি Recursive Function ব্যবহার করে DFS (Depth-First Search) করা যেতে পারে।
javascriptCopy code
function traverseTree(node) {
console.log(node.value);
node.children.forEach(child => traverseTree(child));
}
const tree = {
value: 1,
children: [
{ value: 2, children: [] },
{ value: 3, children: [
{ value: 4, children: [] },
{ value: 5, children: [] }
] }
]
};
traverseTree(tree);
// Output:
// 1
// 2
// 3
// 4
// 5
ログイン後にコピー
Recursion এর উপকারিতা এবং অসুবিধা
- উপকারিতা
-
কোড সরলতা: Recursion জটিল সমস্যাকে সহজভাবে প্রকাশ করতে সাহায্য করে, বিশেষ করে এমন সমস্যা যেখানে সমস্যাগুলি নিজের অনুরূপ।
-
কোড পুনরাবৃত্তি: Recursion প্রায়শই কোডের পুনরাবৃত্তি দূর করে এবং সমাধানগুলোকে ছোট এবং পরিষ্কার করে।
-
কিছু নির্দিষ্ট সমস্যা সমাধানে কার্যকর: যেমন Tree এবং Graph ডেটা স্ট্রাকচার traversal, অথবা Mathematical series এবং sequences।
- অসুবিধা
-
পারফরম্যান্স: প্রত্যেকটি recursive কল একটি নতুন execution context তৈরি করে, যা stack memory তে সংরক্ষণ করা হয়। অতিরিক্ত recursion এর ফলে stack overflow এর ঝুঁকি থাকে।
-
জটিলতা: সাধারণ লুপের তুলনায় কিছু ক্ষেত্রে recursion বোঝা কঠিন হতে পারে, বিশেষ করে শুরুতে।
-
অকার্যকর ফাংশন: কিছু ক্ষেত্রে, recursion অকার্যকর হতে পারে, যদি recursive ফাংশনের প্রতিটি কলের ফলে অনেক অপ্রয়োজনীয় গণনা হয়। এক্ষেত্রে Memoization বা Iterative পদ্ধতির ব্যবহার অধিক কার্যকরী।
以上がJavaScript の再帰に関する詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。