我目前正在阅读《球拍之境》一书,到目前为止我真的很喜欢。但是,在第 4 1/2 章的第 74 页中,有一个我没有得到的代码示例。也许我的头脑拒绝弄清楚,因为我正在度假,但是,我根本不明白它的作用。
(define (winners lst pred)
(cond
[(empty? lst) (list pred)]
[else
(define fst (first lst))
(if (score> (record-score pred) (record-score fst))
(list pred)
(cons pred (winners (rest lst) fst)))]))
他们在书中并没有真正解释它。不过,他们给出了一些提示:
- "该功能的目的是从游戏记录列表中挑选第一名的完成者。
- "我们有以下形状的结构定义:(结构记录(名称分数((">
- ">LST是此类记录的列表,而PRED就是这样一种记录。的确,原始列表是(缺点 pred lst(,它是根据分数排序的。
- "你明白,赢家是一个吃清单的功能,一次要经历一个记录。当至少有一个其他记录时,它会选择第一个,将其命名为 fst,并比较 fst 及其前置记录的分数。根据结果,所有获胜记录都被选中,或者获胜者必须继续寻找得分相等的球员。
我想score>
是一个错字。除此之外,我完全理解代码 - 在语法和语义方面。我只是没有得到它的实际用途。这是什么,为什么有人想要那个?
不幸的是,您显示的代码只是为了向您展示本地定义的工作原理。在同一示例中,您还会看到根本不起作用(define sorted-lst (sort lst ...))
。
下面是第 75 页的完整示例代码,其中包含第 74 页的所有部分:
(define (winning-players lst)
(define sorted-lst (sort lst ...)) ;; local variable
(define (winners lst pred) ;; locally defined procedure
(cond
[(empty? lst) (list pred)]
[else
(define fst (first lst))
(if (score> (record-score pred) (record-score fst))
(list pred)
(cons pred (winners (rest lst) fst)))]))
;; START HERE:
;; uses both local variable and the locally defined procedure
(winners (rest sorted-lst) (first sorted-lst)))
他们试图在下面的代码中展示的是,在winning-players
之外,您无法访问sorted-list
或使用过程winners
因为它隐藏在winning-players
范围内。
例如,如果您尝试在球拍交互窗口中使用(winners ...)
,您将获得:
获胜者:未定义; 无法引用未定义的标识符
如果你明白你可以继续在第5章:)
与球拍捆绑在一起,您拥有书中代码中的所有代码 racket/collects/realm
.有 2 个过程定义称为 winners
。第一个在chapter 10
,第二个在chapter 12
.
至于代码的作用的答案。代码中有错误,因此我们需要修复它。我的猜测是这个分数>比较了两个记录的分数。我猜应该是这样的:
(struct record (name score) #:transparent)
(define (winning-players lst)
(define (score> e1 e2) ; defines a new local procedure
(> (record-score e1) ; that compares two records
(record-score e2)))
;; define sorted-list to be lst sorted by score in decreasing order
(define sorted-lst (sort lst score>))
;; procedure winners reduces the list to the elements
;; that have same score as pred
(define (winners lst pred)
(cond
[(empty? lst) (list pred)]
[else
(define fst (first lst))
(if (score> pred fst) ;; changed to work with records
(list pred)
(cons pred (winners (rest lst) fst)))]))
;; START HERE:
;; uses both local variable and the locally defined procedure
(winners (rest sorted-lst) (first sorted-lst)))
(define scores (list (record "John" 10)
(record "Ben" 5)
(record "Mary" 10)
(record "Owen" 2)))
(winning-players scores)
; ==> (list (record "John" 10) (record "Mary" 10))
它返回所有得分最高的列表。
(winners (cdr lst) (car lst))
在lst
中产生不递减的记录。 pred
代表"前任"(在列表中(。我认为score>
是一个比较数十条记录的过程(即 record-score
似乎产生了记录的分数,score>
比较了这些分数(。
给定列表lst
其前缀的 IOW 生成,以便其中记录条目的分数按非递减顺序排列。
说明指出在应用winners
之前对列表进行排序。这只有在按记录分数的降序排序时才有意义。比递减列表的非递减前缀实际上将包含所有具有相等分数的记录 - 最大值。"赢家"。
清单按不递增顺序排序的前提条件应该在那里更清楚、更突出地说明。