我正在从事计划语言项目,我的代码中遇到了错误

时间:2014-05-05 13:34:05

标签: lambda scheme racket

我正在使用Scheme语言开发一个项目,而且我的代码中出现了错误。问题是当我运行(vide 4 '(2 3 1 5 5 2))的代码时,它会给我(2 (2 3 1 0 6 3))而不是正确答案(3 (2 3 1 0 6 3)),问题出在第一部分。

fidection vide的例子:

(vide 4 '(2 3 1 5 5 2)) ;-> (3 (2 3 1 0 6 3))
(vide 6 '(2 3 1 5 5 2)) ;-> (2 (2 3 1 5 5 0))
(vide 3 '(2 3 1 5 5 2)) ;-> (0 (2 3 0 6 5 2))


(define distribue
  (lambda (n l)
    (if (or (= n 0) (null? l))
        (list n l)
        (let ((r (distribue (- n 1) (cdr l))))
          (list (car r) (cons (+ 1 (car l))(cadr r)))))))

(distribue 5 '(2 3 1 5 5 2)) ;-> (0 (3 4 2 6 6 2))
(distribue 5 '(2 3 1)) ;-> (2 (3 4 2))

(define vide
  (lambda (n l)
    (if (null? l)
        (list n l)
      (let ((r (distribue (car l) (cdr l))))  
        (if (= n 1)
            (list  (car r)  (cons 0 (cadr r)))
            (list (+ (car l) (car r)) (cons (car l)(cadr (vide (- n 1) (cdr l))))))))))

(vide 4 '(2 3 1 5 5 2))

1 个答案:

答案 0 :(得分:1)

问题在于,在最后一行中,术语(+ (car l) (car r))完全不正确; (car l)是输入列表的第一个元素,它可能根本不会影响输出;虽然r不等于1,n也不应该重要。相反,该术语应该是递归调用vide的剩余部分,即{{1 }}。由于您还使用了(car (vide (- n 1) (cdr l))),因此我将cadr中的递归调用绑定在一起,以避免将其调用两次。另外,我将let的{​​{1}}绑定到rdistribue的结果,因为它现在没有在else子句中使用。

以下是更正的实施((if (= n 1) ...)保持不变):

distribue

作为对来自此问题的其他任何人的旁注,我认为此处(define vide (lambda (n l) (if (null? l) (list n l) (if (= n 1) (let ((r (distribue (car l) (cdr l)))) (list (car r) (cons 0 (cadr r)))) (let ((v (vide (- n 1) (cdr l)))) (list (car v) (cons (car l) (cadr v)))))))) 实施的规则类似于游戏Kalah中移动的单个部分,称为Mancala in美国。