━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ データ構造・アルゴリズム論 確認問題1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
●問 (アルゴリズムの表現と時間量) (1) ホーナーの方法は,1変数の整数多項式 an x^n + … + a1 x + a0 の値を (( … ((0・x + an)・x + a{n-1}) … )・x+ a1)・x + a0 の順で計算する.このアルゴリズムをC言語の関数として表したい. 次のプログラムの空欄 (a) と (b) を埋めよ. int eval(int n, int a[], int x) { int val = 0, i; for ( (a) ) { val = (b) ; } return val; } (2) 問題 (1) の関数が,多項式の値を求めるために実行する演算(加算と乗算)の 総回数を,n を使った式で表せ. (3) 問題 (1) の関数を,C言語の再帰関数を使って書き直せ. ────────────────────────────────────── ●答 (アルゴリズムの表現と時間量) (1) (a) i = n; i >= 0; i-- (b) val*x + a[i]. (2) 2n+2 回 (3) eval() を再帰関数として次のように再定義する. int eval(int n, int a[], int x, int val) { if (n < 0) return val; else return eval(n-1, a, x, val*x + a[n]); } eval(n, a, x) の代わりに eval(n, a, x, 0) を呼べばよい. [解説] (1) ホーナーの方法では,添え字 i を n から 0 まで変化させながら, 0 を初期値として「x を掛けて ai を足す」という計算を繰り返せばよい. C言語の関数で表したアルゴリズムを以下に示す. int eval(int n, int a[], int x) { int val = 0, i; for (i = n; i >= 0; i--) { val = val*x + a[i]; } return val; } なお,val を a[n] で初期化して,for 文の反復回数を1回減らしてもよい. ただし,n が負の場合に a[n] をアクセスしないよう配慮が必要. また,i を 0 から始めて 1 ずつ増やすなら,配列要素 a[n-i] を参照する. (2) 上記の関数 eval() では,繰り返しごとに,乗算1回と加算1回の計2回実行する. 繰り返し回数は n+1 なので,演算の総回数はその積 2(n+1) = 2n+2 回. (3) 第4引き数で累計値を受け渡すことに注意. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 授業のホームページ 山田 俊行 https://www.cs.info.mie-u.ac.jp/~toshi/