【问题标题】:Scheme List Function : Where am i wrong?方案列表功能:我哪里错了?
【发布时间】:2017-01-24 22:39:17
【问题描述】:
我是 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)))
【问题讨论】:
标签:
function
scheme
racket
【解决方案1】:
您的代码中有 4 个错误。
您可能在帮助程序中使用lst,这在整个过程中是相同的,而您可能应该使用kur,这是每次迭代的列表的其余部分。因此,您的基本条件不会影响任何迭代。这可能是您看到的错误的根本原因。
如果kur 是null?,则列表中没有小于或等于下一个元素的元素。当kur 是null? 时执行(cdr kur) 表示违反合同,因为cdr 应该始终呈现一对。这是您看到的错误。
prefix-helper 周围有括号,以替代 if。这意味着递归的结果被假定为另一个函数,然后应用。由于result 是一个列表结构,如果它没有首先因其他错误而失败,它将发出application: not a procedure 的信号。
您从第一个元素开始帮助器。这意味着您的结果变成了一个虚线列表,例如。 (1 2 . 3)。如果这不是故意的,那么您应该从包含第一个元素的列表开始,而不仅仅是元素。
【解决方案2】:
使用“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)]
)))