Scheme 计划中的约瑟夫
约瑟夫斯问题的这一实现有哪些不足之处?对于那些不熟悉约瑟夫斯问题的人来说,目标是从循环链接列表中删除每三个条目,直到只剩下一个条目。在本例中,我删除了每个“mth”值Scheme 计划中的约瑟夫,scheme,josephus,Scheme,Josephus,约瑟夫斯问题的这一实现有哪些不足之处?对于那些不熟悉约瑟夫斯问题的人来说,目标是从循环链接列表中删除每三个条目,直到只剩下一个条目。在本例中,我删除了每个“mth”值 (定义(joseph lst) (let((m(+1(随机长度lstЮЮ))) (定义(joseph-h i xlst mlst) (cond)(通过创建一个列表并从中删除元素(“杀死”人),您对算法的理解过于字面化。一个更简单的解决方案是使用算术运算对问题进行建模,下面是一个可能的实现,它改编自我自己的: 例如,要查看在杀死每三
(定义(joseph lst)
(let((m(+1(随机长度lstЮЮ)))
(定义(joseph-h i xlst mlst)
(cond)(通过创建一个列表并从中删除元素(“杀死”人),您对算法的理解过于字面化。一个更简单的解决方案是使用算术运算对问题进行建模,下面是一个可能的实现,它改编自我自己的:
例如,要查看在杀死每三个人后列表中幸存的位置(1 2 3 4 5 6 7)
,请执行以下操作:
(joseph 7 3)
=> 4
Wikipedia提供了一个有趣的关于这个问题可能的解决方案,我的解决方案在将其转换为尾部递归后,对所示的简单python函数进行了调整。我在中给出了三个解决方案。最字面的版本以m为单位从n个项目的列表中删除,将列表表示为循环列表:
(define (cycle xs)
(set-cdr! (last-pair xs) xs) xs)
(define (josephus3 n m)
(let loop ((k (- m 1)) (alive (cycle (range 0 n))) (dead '()))
(cond ((= (car alive) (cadr alive))
(reverse (cons (car alive) dead)))
((= k 1)
(let ((dead (cons (cadr alive) dead)))
(set-cdr! alive (cddr alive))
(loop (- m 1) (cdr alive) dead)))
这是通过从活动
列表中实际删除被杀死的元素并将它们放置在死
列表中来执行删除操作的。范围
函数来自my;它返回从0到n-1的整数:
(define (range first past . step)
(let* ((xs '()) (f first) (p past)
(s (cond ((pair? step) (car step))
((< f p) 1) (else -1)))
(le? (if (< 0 s) <= >=)))
(do ((x f (+ x s))) ((le? p x) (reverse xs))
(set! xs (cons x xs)))))
(定义(范围第一步)
(让*((xs’())(f先)(p过去)
(秒)(成对台阶)(轿厢台阶))
((
最初的约瑟夫斯问题在3步中杀死了41人,剩下31人作为幸存者,从1开始计算:
(约瑟夫斯3413)
(2 5 8 11 14 17 20 23 26 29 32 35 38 0 4 9 13 18 22 27 31 36
4061219253339716283710412133430)
您可能还喜欢上的其他两个版本。Darn,这个解决方案简单多了。很酷,我来看看。
(define (cycle xs)
(set-cdr! (last-pair xs) xs) xs)
(define (josephus3 n m)
(let loop ((k (- m 1)) (alive (cycle (range 0 n))) (dead '()))
(cond ((= (car alive) (cadr alive))
(reverse (cons (car alive) dead)))
((= k 1)
(let ((dead (cons (cadr alive) dead)))
(set-cdr! alive (cddr alive))
(loop (- m 1) (cdr alive) dead)))
(define (range first past . step)
(let* ((xs '()) (f first) (p past)
(s (cond ((pair? step) (car step))
((< f p) 1) (else -1)))
(le? (if (< 0 s) <= >=)))
(do ((x f (+ x s))) ((le? p x) (reverse xs))
(set! xs (cons x xs)))))