再帰(アルゴリズムC 第1巻 p.59) に関する演習です。 再帰のコツは、ループと同様に、まず最初に終了条件を考えることです。
(1) 次のような数列がある。これらの数列の漸化式を書きなさい。
f(n) = n! の漸化式 f(n) = 20 + 21
+ 22 + ... + 2n
の漸化式 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
第 n 項 f(n) の漸化式 f(x,n) = a0 xn +
a1 xn-1 + ...
an-1 x + an
のホーナー法を使っての漸化式
(2) 以下のような関数 rule() がある(教科書とは若干異なる)。
関数 mark() は定規に線を引く関数であり、
例えば mark( 13, 3 ) は 13 の位置に高さ 3 の線を引く。
ここで、rule( 4, 12, 3); を実行した場合、
定規にはどのように線が引かれていくかを、順番に図示しなさい。
void rule(int left, int right, int height){
int middle = (left+right)/2;
if( height>0 ){
mark(middle, height);
rule(middle, right, height-1);
rule(left, middle, height-1);
}
}
(1) は漸化式を作る問題です。例えば、初項 1、等差 1 の
等差級数 f(n) = n + (n-1) + ... + 2 + 1 の漸化式は
このようになります。
ホーナー法は高次多項式を (ax + b) の形に展開していく方法です。
例えば、f(x) = 1x4 + 2x3 + 3x2 + 4x
+ 5
をこの方法で展開すると次のようになります。
(2) は再帰で実行される順番を考える問題
(アルゴリズムC 第1巻 p.62)
です。
例えば mark(13,3) を実行すると、次のような線が
引かれることになります。

この mark() 関数の引数が、どういう順番で何になるかを考えて、
図に書いてみてください。
次の計算を行なう関数を再帰で書きなさい。
f(x) = 1x4 + 2x3 + 3x2 + 4x
+ 5
また、main() 関数でそれらの関数を呼び出し、
以下の値を計算させて表示させなさい。
f(x) = 1x4 + 2x3 + 3x2 + 4x
+ 5実行例: % ./a.out 10! = 3628800 2^0 + 2^1 + 2^2 + ... + 2^9 = 1023 fibonacci 20: 6765 f(2) = 57.00
関数を作る場合、問題1で考えた漸化式が参考になると思います。
例えば、このような漸化式

を関数にすると、次のようになります。
int tousa(int n){
if( n==0 ){
return 0;
}else{
return n + tousa(n-1);
}
}
同様にして、他の関数も作ってみてください。 また、ホーナー法を用いる関数では簡単のため、 係数 an は次のようにグローバルな配列として宣言しても良い。
#define N 4
double a[N+1] = { 1, 2, 3, 4, 5 };
配列 a と展開式はこのように対応します。
ex04-3-skel.c
は、実行すると
star.ps という PostScript ファイルを生成する。
これを表示すると次のような画像になっている。

このプログラムを変更して、
このような画像
にしなさい。
ex04-3-skel.c
の中で、描画しているのは star 関数
(アルゴリズムC 第1巻 p.68)
です。
この関数を変更してください。この関数の中で使われている line 関数は
線を引く関数で、例えば line(1,2,3,4) とした場合は、
座標 (1,2) から (3,4) までの線が引かれます。
これ、結構難しいです。 できた人はコッホ曲線にも挑戦してみてください。