階乗を計算するプログラムは次のように書ける.
def factorial(N) {
F = 1;
for ( I = 1; I <= N; I++ )
F *= I;
return F;
}
ここで,
def rfactorial(N) {
if ( N == 1 )
return 1;
else
return N*rfactorial(N-1);
}
あるいは, 短いプログラムが好きなら
def rfactorial(N) { return N==1 ? 1 : N*rfactorial(N-1); }
という書き方もできる. このように, 関数の実行中に自分自身を
呼び出すことを再帰 (recursion) という.
プログラムが書きやすい場合がある. (パラメタの数が少ない場合 に帰着できる場合など.)
問題の構造上, 再帰で書かざるを得ない場合もある.
通常のループで書けるプログラムを再帰で書くと一般に効率は落ちるが, これは実行機構による.
それ以上に大変なことになる場合もある.
def a(N) {
if ( N == 1 || N == 2 )
return 1;
else
return A*a(N-1)+B*a(N-2);
}
と書いたとする. このとき, 例えば
def list_append(A,B) {
if ( A == [] )
return B;
else {
L1 = list_append(cdr(A),B);
return cons(car(A),L1);
}
}
これは,
def list_insert(A,List) {
if ( List == [] )
return [A];
else if ( A >= car(List) )
return cons(A,List);
else {
/* 先頭は car(List); A は cdr(List) に insert すればよい */
L1 = list_insert(A,cdr(List);
return cons(car(List),L1);
}
}
list_insert を使って, リストを大きい順に整列するプログラム
を書け.例えば, リストの各要素は実はなんでもよい. 特にまたリストで あってもよい.
def add_all(Obj) {
if ( type(Obj) <= 1 ) /* Obj is a number */
return Obj;
else if ( type(Obj) == 4 ) {
/* Obj is a list */
if ( Obj == [] )
return 0;
else {
A = add_all(car(Obj));
B = add_all(cdr(Obj));
return A+B;
}
} else
error("add_all : invalid argument");
}
[1] add_all([1,[2,[3,4],5],[6,7,8],9,[[],11,[12]]]);
68
ここで, type(Obj) は Obj の型を調べる関数で
| Obj | 0 | 0 でない数 | 多項式 | 有理式 | リスト | 配列 |
| type(Obj) | 0 | 1 | 2 | 3 | 4 | 5 |
list_append を使ってよい.)