"球拍王国 "中的怪异代码示例

问题描述 投票:5回答:3

我现在正在看《Realm Of Racket》这本书,目前我非常喜欢这本书。然而,在第412章第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)))]))

他们在书中并没有真正解释它。不过,他们给了一些提示。

  • "这个函数的目的是为了从游戏记录列表中选出第一名的选手。"
  • "我们有一个如下形状的结构定义。(struct record (name score))"
  • "lst 是此类记录的列表,并且 预测 是这样的记录之一。事实上,原名单是 (cons pred lst),而且是按照分数排序的。"
  • "你懂的,赢家是一个吃单子的功能,每次只翻一个记录。当至少有一个其他记录时,它选择第一个,命名为 fst的分数,并比较 fst 及其前身。根据结果,所有的胜利记录都被摘掉了,或者胜利者必须继续寻找同等分数的球员。"

我想 score> 是一个错别字。除此之外,我完全理解代码--在语法和语义方面。我只是不明白其中的实际用途。这是什么,为什么会有人想要这个?

lisp scheme racket
3个回答
5
投票

不幸的是,你所显示的代码只是为了向你展示本地定义是如何工作的。在同一个例子中,你还看到 (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.

至于回答代码的作用。代码中存在错误,所以我们需要修正。我猜测是 score>比较两条记录的分数。我猜应该是这样的。

(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))

它返回所有最高分的记录列表


4
投票
(winners (cdr lst) (car lst))

产生非递减的连续记录,在 lst. pred 代表 "前身"(在列表中)。我假设 score> 是一个比较记录分数的过程(即 record-score 似乎产生了一个记录的分数,而 score> 比较这些分数)。)

也就是说,对于一个给定的列表 lst 其前缀的产生使得其中的记录条目的分数是不递减的。

该说明指出,该列表是 排序 之前 winners 被应用。只有当它以 递减 记录的得分顺序。比非递减列表前缀的递减列表实际上将包含记录都具有相同的分数 - 最大的一个。赢家"。

列表按非递增顺序排列的前提条件应该是这样的: 1. 更加明确和突出 在那里。

© www.soinside.com 2019 - 2024. All rights reserved.