Рассчитать суммы с накоплением - PullRequest
0 голосов
/ 29 июня 2010

Процедура накопления определяется следующим образом:

(define (accumulate combiner null-value term a next b)
  (if (> a b) null-value
      (combiner (term a)
                (accumulate combiner null-value term (next a) next b))))

задача 1: x ^ n Решение: рекурсивное без накопления

(define (expon x n)
  (if (> n 0) (* x
                 (expon x (- n 1))
              )
              1))

задача 2: x + x ^ 2 + x ^ 4 + x ^ 6 + ... +, вычислить для заданных n первых n элементов последовательности.

задача 3: 1 + х / 1! + х ^ 2/2! + ... + x ^ n / n !; рассчитать сумму для данного х, п возможно неправильное решение:

(define (exp1 x n)
 (define (term i)
   (define (term1 k) (/ x k))
   (accumulate * 1 term1 1 1+ i))
  (accumulate + 0 term 1 1+ n))

почему предыдущий код неверен:

(exp1 0 3) -> 0; Должно быть 1 (exp1 1 1) -> 1; Должно быть 2

1 Ответ

3 голосов
/ 30 июня 2010

Прежде всего, я бы сказал, что ваша процедура EXP1 работает на слишком низком уровне, чтобы ее можно было определить в терминах ACCUMULATE, и ради проницательности вместо этого переписайте ее в терминах сумм и факториалов:

(define (sum term a b)
  (accumulate + 0 term a 1+ b))

(define (product term a b)
  (accumulate * 1 term a 1+ b))

(define (identity x) x)

(define (fact n)
  (if (= n 0)
      1
      (product identity 1 n)))

(define (exp1 x n)
  (define (term i)
    (/ (expon x i) (fact i)))
  (sum term 1 n))

Теперь к вашему вопросу: причина, по которой вы получаете (EXP1 0 3) → 0, не более чем то, что вы забыли добавить 1 в начале серии, и просто вычисляете х / 1! + х ^ 2/2! + ... + x ^ n / n!

Изменение EXP1 для включения отсутствующего термина работает, как и ожидалось:

(define (exp1 x n)
    (define (term i)
          (/ (expon x i) (fact i)))
    (+ 1 (sum term 1 n)))

=> (exp1 0 3)
1
=> (exp1 1 1)
2
...