DrRacket与累加器相互递归函数

时间:2013-12-09 08:05:49

标签: racket

  (define-struct person (name house kids))

;;一个人是(make-person String String ListOfPerson) ;;插补。一个人,有姓名,房子和孩子名单。

  (define P0  (make-person "Draco"      "Slytherin"  empty))
  (define P1  (make-person "Nymphadora" "Hufflepuff" empty))
  (define P2  (make-person "Sirius"     "Griffindor" empty))
  (define P3  (make-person "Regulus"    "Slytherin"  empty))
  (define P4  (make-person "Bellatrix"  "Slytherin"  empty))
  (define P5  (make-person "Andromeda"  "Slytherin"  (list P1)))
  (define P6  (make-person "Narcissa"   "Slytherin"  (list P0)))
  (define P7  (make-person "Walburga"   "Slytherin"  (list P2 P3)))
  (define P8  (make-person "Alphard"    "Slytherin"  empty))
  (define P9  (make-person "Cygnus"     "Slytherin"  (list P4 P5 P6)))
  (define P10 (make-person "Irma"       "Slytherin"  (list P7 P8 P9)))

原始结构化参考

   ;; Person -> Natural
   ;; Count number of people in a tree
   (check-expect (count P0) 1)
   (check-expect (count P5) 2)
   (check-expect (count P10) 11)

(define (count p)  
  (local 
    [(define (count/person p)
       (add1 (count/lop (person-kids p))))
     (define (count/lop lop)
       (cond [(empty? lop) 0]
             [else
              (+ (count/person (first lop))
                 (count/lop (rest lop)))]))]
    (count/person p)))

这是解决方案

(define (count p)  
  (local 
    [(define (count/person p result todo)
       (count/lop (add1 result)
                  (append (person-kids p) todo)))
     (define (count/lop result todo)
       (cond [(empty? todo) result]
             [else
              (count/person (first todo) 
                            result
                            (rest todo))]))])
  (count/person p 0 empty))

;; Accumulator result is Natural
;; Invariant: the total computed so far
;; Accumulator todo is (listof Person)
;; Invariant: persons not yet visited by count/person

我无法理解这是如何来自最初的正常互参考解决方案,有人可以向我解释这个吗?

1 个答案:

答案 0 :(得分:0)

您的解决方案不符合基本设计配方。 这是尝试制定一个直接的解决方案:

(define-struct person (kids))

; sum : list-of-numbers -> number
(define (sum xs)
  (cond
    [(empty? xs) 0]
    [else        (+ (first xs) (sum (rest xs)))]))

; count : person -> number
(define (count p)
  (cond 
    [(empty? (person-kids p)) 1]             ; p is 1 person, 0 kids
    [else (+ 1                               ; p is 1 person and 
             (sum (map count                 ; we must sum over the
                       (person-kids p))))])) ; count of each kid

在“如何设计程序”的第30章和第31章中,您可以了解从此样式到累加器样式(您的解决方案使用的)的转换。转换的详细信息见第31.3节。

HtDP section 31.3 'Transforming Functions into Accumulator-Style'