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