練習問題 1 (解答例)


1. フィボナッチ関数について、
  • 素直に再帰的定義を Scheme の program として実現せよ。
  • 素直に再帰的定義にしたがって fib を記述した場合、 同じ計算をなんども繰り返すことになる。 同じ計算を何度も繰り返すことがないような、 末尾再帰を用いた fib2 を書け。
  • 素直に再帰的定義を用いると、以下の様に定義できる( n = 0, 1 を誤魔化した)
    (define (fib n)
        (if (> n 1)
    	(+ (fib (- n 1)) (fib (- n 2)))
    	n))
    
  • 末尾再帰をもちいる為に、 fib-iter をもちいる。 fib-iter は、 引数として i, n, fib(i), fib(i-1) をあらわす変数をもっている。
    (define (fib-iter i n fib-0 fib-1)
        (if (= i n)
    	fib-0
    	(fib-iter (+ i 1) n (+ fib-0 fib-1) fib-0)))
    
    (define (fib2 n)
        (if (> n 1)
    	(fib-iter 1 n 1 0)
    	n))
    

問題

2. 変数 a, b の最大公約数を求める program を書け

ユークリッドの互助法を用いたプログラム(mygcd)は以下の通りである。
(define (mygcd n m)
   (if (= (remainder n m) 0)
       m
       (mygcd m (remainder n m)))))

;;; 割算 2 回するのが嫌なら
(define (mygcd2 n m)
   (mygcd2-body n m (remainder n m)))

(define (mygcd2-body n m k)
   (if (= k 0)
       m
       (mygcd2 m k)))

;;; 本当は、4. で教える let を使ってこんな感じ
(define (mygcd3 n m)
   (let ((k (remainder n m)))
      (if (= k 0)
          m
          (mygcd3 m k))))

問題


98.11.16/ Tomio KAMADA: kamada@seg.kobe-u.ac.jp