首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >约瑟夫斯计划

约瑟夫斯计划
EN

Stack Overflow用户
提问于 2013-12-05 16:16:04
回答 2查看 313关注 0票数 1

约瑟夫斯问题的实施有何不足?对于那些不熟悉约瑟夫斯问题的人来说,目标是删除循环链接列表中的每三个条目,直到只剩下一个。在本例中,我将删除每个"mth“值。

代码语言:javascript
复制
(define (joseph lst)  
(let ((m (+ 1 (random (length lst)))))
(define (joseph-h i xlst mlst)
 (cond ((<= (length xlst) 1) xlst)
       ((null? (cdr mlst)) 
        (joseph-h i xlst xlst))
       ((= i m) 
        (joseph-h 1 (delete (car mlst) xlst) (cdr mlst)))
       (else 
        (joseph-h (+ i 1) xlst (cdr mlst)))))
 (joseph-h 0 lst lst)))

 (joseph (list 1 2 3 4 5 6 7))


 (define (delete v lst)
   (cond ((= v (car lst)) 
          (cdr lst))
         (else
          (cons (car lst) (delete v (cdr lst)))))) 

我总是以名单上的最后一个数字作为答案。我知道这是不对的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-05 16:24:15

通过创建一个列表并从其中删除元素(“杀死”人),你就把算法看得太简单了。一个更简单的解决方案是使用算术操作来建模这个问题,下面是一个可能的实现,它来自于我自己的先前的回答

代码语言:javascript
复制
(define (joseph n k)
  (let loop ([i   1]
             [acc 0])
    (if (> i n)
        (add1 acc)
        (loop (add1 i)
              (modulo (+ acc k) i)))))

例如,要查看在杀死每三个人之后在列表'(1 2 3 4 5 6 7)中幸存的位置,请执行以下操作:

代码语言:javascript
复制
(joseph 7 3)
=> 4

维基百科提供了一个关于这个问题的可能解决方案的有趣的讨论,我的解决方案适应了简单的python函数,在将它转换成尾递归之后。

票数 2
EN

Stack Overflow用户

发布于 2013-12-05 16:35:44

我在我的博客给出了三个解决方案。最直接的版本按m的步骤从n项列表中删除,将列表表示为循环列表:

代码语言:javascript
复制
(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)))

这是通过从alive列表中实际删除被删除的元素并将它们放到dead列表中来进行删除的。range函数来自于我的标准前奏;它将整数从0返回到n-1

代码语言:javascript
复制
(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)))))

最初的约瑟夫斯问题在3步中杀死了41人,留下第31个人作为幸存者,从1开始计算:

(josephus3 41 3) (2 5 8 11 14 17 20 23 26 32 32 38 0 4 9 13 22 27 31 36 6 12 25 33 39 7 16 16 37 10 24 1 21 3 34 15 30)

您可能还会喜欢我的博客的其他两个版本。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20405081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档