LINUX.ORG.RU

Ещё одно упражнение (SICP)


0

0

Извините, если уже достал со своими идиотскими вопросами, но опять застрял на упражнении со списками.

Итак, задание:
Переопределить ф-цию count-leaves из п. 2.2.2 (там она была объявлена "по определению": если дерево пустое - 0, если атом - 1, в противном случае - (+ (count-leaves (car x)) (count-leaves (cdr x)))) в виде аккумуляции:

(define (count-leaves t)
  (accumulate <??> <??> (map <??> <??>)))

Аккумуляция это такая штука:

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

Например, (accumulate + 0 '(1 2 3 4 5)) = 15
★★★★★

(define (count-leaves t)
  (accumulate + 0 (map (lambda (sub-tree)
                          (if (not (pair? sub-tree))
                              1
                              (count-leaves sub-tree)))
                       t)))
;Value: count-leaves

(count-leaves (list 1 2 (list 3 4 (list 5 6)) (list 7 8) 9))
;Value: 9

satanic-mechanic
()
Ответ на: комментарий от seiken

Если немного не следовать шаблону, можно вынести if из лямбды 
на уровень выше и получить:

(define (count-leaves tree)
  (if (pair? t) (accumulate + 0 (map count-leaves tree)) 1))

во-первых, accumulate - это на самом деле fold-right.
во-вторых, стоит сравнить этот код с кодом, который я привел 
для предыдущего упражнения и попробовать найти отличия :)

grob ★★★★★
()
Ответ на: комментарий от grob

Да, один-в-один практически. Но оно и понятно, обоим ф-циям нужен список листьев.

seiken ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.