階乗を計算するプログラムは次のように書ける.
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
を使ってよい.)