【发布时间】:2018-07-23 06:26:37
【问题描述】:
这是来自How To Design Programs 的家谱 (FT) 的数据定义
(define-struct no-parent [])
(define-struct child [father mother name date eyes])
(define NP (make-no-parent))
; An FT is one of:
; – NP
; – (make-child FT FT String N String)
; Oldest Generation:
(define Carl (make-child NP NP "Carl" 1926 "green"))
(define Bettina (make-child NP NP "Bettina" 1926 "green"))
; Middle Generation:
(define Adam (make-child Carl Bettina "Adam" 1950 "hazel"))
(define Dave (make-child Carl Bettina "Dave" 1955 "black"))
(define Eva (make-child Carl Bettina "Eva" 1965 "blue"))
(define Fred (make-child NP NP "Fred" 1966 "pink"))
; Youngest Generation:
(define Gustav (make-child Fred Eva "Gustav" 1988 "brown"))
我设计了一个函数来计算特定家谱中的所有人。
该函数消耗一棵家谱并计算树中的子结构,方法是简单地在每个父级上重复并加 1 以组合对父级的函数调用,如果没有父级则返回 0
;; FT -> Natural
;; counts the child structures in an-ftree
(define (count-persons an-ftree)
(cond
[(no-parent? an-ftree) 0]
[else (+ 1 (count-persons (child-father an-ftree))
(count-persons (child-mother an-ftree)))]))
我的功能 - 在 Gustav 上启动时 - 计算了 Fred 和 Eva,然后是 Eva 的父母 Carl 和 Betrtina。它没有到达亚当和戴夫。
(check-expect (count-persons Dave) 3) ✓
(check-expect (count-persons Gustav) 7) ✗ (it's 5)
当我在 Gustav 上调用我的函数时,我如何(如果我想计算所有祖先,包括叔叔)到达 Adam 和 Dave?
tl;博士
基本上如何遍历上面的所有世代?如何从“Gustav”访问“Dave”(没有提及他们!)。如何计算所有的祖先,不仅仅是父母,然后是他们的父母,等等。
【问题讨论】:
-
我不认为“祖先”是你要找的词。如果祖父母的孩子也应该计算在内,您是否要计算任何有上下关系的人,包括表亲、侄女、侄子等?
-
如果是这种情况,并且您想在两个方向上跟踪关系,那么 Tree 并不能完全表示数据,但 Graph 可能。如何设计程序在Traversing Graphs 和A Problem with Generative Recursion 中得到了解决。要为“家谱”图正确执行此操作,需要 accumulator 记住您已经见过哪些人,以避免多次遍历图的同一部分。
-
谢谢。是的,我认为数据定义不适合我尝试做的事情。
-
我添加了一个包含家谱图数据定义的答案。这应该可以帮助您入门。
标签: scheme racket racket-student-languages