解説
関数の中から、その関数自身を呼び出すような処理を「再帰(的)処理」、そういった関数を「再帰関数」と呼びます。
再帰処理は、似た処理を何度も繰り返すという意味で、ループ処理に似ています。しかし、大きく違う点もあります。それは、関数は呼び出されるごとにローカル変数が作成されるという点です。そのため、何度も繰り返すが個別の処理として行いたい場合に、再帰関数は向いています。
また再帰関数で、関数を呼び出す際は、1回だけである必要はありません。複数回でも構いません。
たとえば移動範囲の計算をおこなう際に、上下左右の4方向の判定を繰り返したいとします。その際は、再帰関数内で、自身の関数を上下左右に値を変えて4回呼び出せば簡単に記述できます。同じような処理をループ処理で書くのは、少し面倒で、工夫が必要になります。
最後に、再帰関数を作る場合は、終了条件を設定しておかなければなりません。そうしなければ、無限ループのようになってしまい問題が発生します。
サンプル
再帰関数の処理を、JavaScriptで簡単に書いてみます。
<html>
<head>
<title>「再帰関数」のサンプル</title>
</head>
<body>
<pre><script type="text/javascript">
// 地図サイズ
var w = 8;
var h = 8;
// 移動コスト表
var cost = [
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
3, 3, 1, 1, 1, 1, 5, 5,
3, 3, 3, 1, 1, 5, 5, 5,
3, 3, 3, 3, 1, 5, 5, 5,
3, 3, 3, 1, 1, 5, 5, 5,
3, 3, 1, 1, 1, 1, 5, 5,
1, 1, 1, 1, 1, 1, 1, 1
];
// 移動範囲表
var move = [
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
];
// 移動範囲を計算
calcMove(6, 4, 5, w, h, cost, move);
// 再帰関数
function calcMove(movePow, x, y, w, h, cost, move) {
if (movePow <= 0) return;
if (move[x + y * w] > movePow) return;
move[x + y * w] = movePow;
if (x > 0) {
var x2 = x - 1;
var c = cost[x2 + y * w];
calcMove(movePow - c, x2, y, w, h, cost, move)
}
if (x + 1 < w) {
var x2 = x + 1;
var c = cost[x2 + y * w];
calcMove(movePow - c, x2, y, w, h, cost, move)
}
if (y > 0) {
var y2 = y - 1;
var c = cost[x + y2 * w];
calcMove(movePow - c, x, y2, w, h, cost, move)
}
if (y + 1 < h) {
var y2 = y + 1;
var c = cost[x + y2 * w];
calcMove(movePow - c, x, y2, w, h, cost, move)
}
}
// 結果を出力
for (var y = 0; y < h; y ++) {
var sLn = "";
for (var x = 0; x < w; x ++) {
var s = move[x + y * w];
if (s == 0) {
sLn += "[ ]";
} else {
sLn += "[" + s + "]";
}
}
document.writeln(sLn);
}
</script></pre>
</body>
</html>
[ ][ ][ ][ ][1][ ][ ][ ] [ ][ ][ ][1][2][1][ ][ ] [ ][ ][1][2][3][2][ ][ ] [ ][ ][ ][3][4][ ][ ][ ] [ ][ ][ ][2][5][ ][ ][ ] [ ][ ][2][5][6][1][ ][ ] [ ][ ][3][4][5][4][ ][ ] [ ][1][2][3][4][3][2][1]
