我是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)))
答案 0 :(得分:0)
您的代码中有4个错误。
您可能在助手中使用lst
,这在整个过程中是相同的,而您可能应该使用kur
,这是每次迭代时列表的其余部分。因此,您的基本条件不会在任何迭代中出现。这可能是您看到的错误的根本原因。
一个列表,其中没有任何元素小于或等于下一个元素,您不会检查kur
是否为null?
。 (cdr kur)
kur
null?
时cdr
表示合同违规,因为prefix-helper
应始终显示一对。这是你看到的错误。
if
替代result
附近有括号。这意味着递归的结果被假定为随后应用的另一个函数。由于application: not a procedure
是一个列表结构,如果它首先没有在其他错误上失败,它将发出(1 2 . 3)
信号。
您使用第一个元素启动帮助程序。这意味着您的结果将成为虚线列表,例如。 std::cout << "Testing" << std::endl;
。如果这不是预期的话,那么你应该用一个包含第一个元素而不仅仅是元素的列表来启动它。
答案 1 :(得分:0)
使用名为let&#39;可能有助于澄清步骤:
(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)]
)))