方案列表功能:我哪里错了



我是Scheme的新手,我正在尝试编写一个返回列表降序前缀的函数。有人能解释一下我的代码哪里错了吗?我用(prefix (list 3 2 1 5))测试了它,我不断地得到这个错误:

cdr: contract violation
expected: pair?
given: '()
(define (prefix lst)
(define (prefix-helper kur result)
(let((next (car(cdr lst))))
(if (<= (car lst) next) result
((prefix-helper (cdr kur) (cons next result))))))
(prefix-helper lst (car lst)))

您的代码中有4个错误。

  1. 您可能在助手中使用lst,这在整个过程中是相同的,而您可能应该在每次迭代时使用kur,这是列表的其余部分。因此,您的基本条件不会影响任何迭代。这可能是您所看到的错误的根本原因。

  2. 一个列表,其中没有小于或等于您不检查kur是否为null?的下一个元素。当kurnull?时执行(cdr kur)表示违反合同,因为cdr应该总是呈现一对。这就是您看到的错误。

  3. if的替代方案中,prefix-helper周围有括号。这意味着递归的结果被假定为随后应用的另一个函数。由于result是一个列表结构,如果它没有首先在其他错误上失败,它将发出application: not a procedure的信号。

  4. 从第一个元素开始辅助对象。这意味着你的结果变成了一个虚线列表,例如(1 2 . 3)。如果这不是有意的,那么应该以包含第一个元素的列表开始,而不仅仅是元素。

使用"named let"可能有助于澄清步骤:

(define (prefix lst)
(let loop ((lst lst)                  ; starting with full list
(pf '()))                  ; empty prefix list
(cond
[(empty? lst)                     ; if list over, return prefix list
(reverse pf)]       
[(or (empty? pf)                  ; if just starting or 
(< (first lst) (first pf)))  ; still descending
(loop (rest lst)                 ; add element to prefix list and 
(cons (first lst) pf))]    ; loop again with rest of the list
[else                             ; if not descending, return prefix list; 
(reverse pf)]
)))

相关内容

最新更新