scheme解決約瑟夫環問題(續)

2021-09-23 16:23:25 字數 3634 閱讀 1221

sicp的習題3.22,也就是以訊息傳遞的風格重新實現佇列,我的解答如下:

(define (make

-queue)

(let ((front

-ptr 

'())

(rear

-ptr 

'()))

(define (set

-front

-ptr! ptr) (set! front

-ptr ptr))

(define (set

-rear

-ptr! ptr) (set! rear

-ptr ptr))

(define (empty

-queue?) (null? front

-ptr))

(define (front

-queue)(if

(empty

-queue?)

(error 

"front called with an empty queue")

(car front

-ptr)))

(define (insert

-queue! item)

(let ((new

-pair (cons item 

'())))

(cond ((empty

-queue?)

(set

-front

-ptr! new

-pair)

(set

-rear

-ptr! new

-pair))

(else

(set

-cdr! rear

-ptr new

-pair)

(set

-rear

-ptr! new

-pair)))))

(define (delete

-queue!)

(cond ((empty

-queue?)

(error 

"delete! called with an empty queue

"queue))

(else

(set

-front

-ptr! (cdr front

-ptr)))))

(define (dispatch m)

(cond ((eq? m 

'front-queue) (front-queue))

((eq? m 

'empty-queue?) (empty-queue?))

((eq? m 

'insert-queue!) insert-queue!)

((eq? m 

'delete-queue!) delete-queue!)

(else

(error 

"unknow method

"m))))

dispatch))

(define (front

-queue z) (z 

'front-queue))

(define (empty

-queue? z) (z 

'empty-queue?))

(define (insert

-queue! z item) ((z 

'insert-queue!) item))

(define (delete

-queue! z) ((z 

'delete-queue!)))

由此,我才知道自己竟然一直沒有想到,scheme完全可以模擬單向迴圈鍊錶,整整第三章都在講引入賦值帶來的影響,而我卻視而不見。在引入了改變函式後,資料物件已經具有oo的性質,模擬鍊錶、佇列、table都變的易如反掌。首先,模擬節點物件,節點是乙個序對,包括當前節點編號和下乙個節點:

(define (make

-node n next) (cons n next))

(define (set

-next

-node! node next) (set

-cdr! node next))

(define (set

-node

-number! node n) (set

-car! node n))

(define (get

-number node) (car node))

(define (get

-next

-node node) (cdr node))

有了節點,實現了下單向迴圈鍊錶:

(define (make

-cycle

-list n)

(let ((head (make

-node 1'

())))

(define (make

-list current i)

(let ((next

-node (make

-node (+i 

1) '())))

(cond ((

=i n) current)

(else

(set

-next

-node! current next

-node)

(make

-list next

-node (+i 

1))))))

(set

-next

-node! (make

-list head 

1) head) 

head))

make-cycle-list生成乙個有n個元素的環形鍊錶,比如(make-cycle-list 8)的結果如下

#0=(1 2 3 4 5 6 7 8 . #0#)

drscheme形象地展示了這是乙個迴圈的鍊錶。那麼約瑟夫環的問題就簡單了:

(define (josephus

-cycle n m)

(let ((head (make

-cycle

-list n)))

(define (josephus

-iter prev current i)

(let ((next

-node (get

-next

-node current)))

(cond ((eq? next

-node current) (get

-number current))((=

1i)(set

-next

-node! prev next

-node)

(josephus

-iter prev next

-node m))

(else

(josephus

-iter current next

-node (-i 

1))))))

(josephus

-iter head head m)))

從head節點開始計數,每到m,就將當前節點刪除(通過將前乙個節點的next-node設定為current的下乙個節點),最後剩下的節點的編號就是答案。

文章**莊周夢蝶  ,原文發布時間 2008-04-16

約瑟夫環問題的解決

約瑟夫環問題介紹 已知n個人 以編號1,2,3.n分別表示 圍坐在一張圓桌周圍。從編號為1的人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到圓桌周圍的人全部出列。include include include typedef int datat...

python解決約瑟夫環問題

問題描述 編號為 1 n 的 n 個士兵圍坐在一起形成乙個圓圈,從編號為 1 的士兵開始依次報數 1,2,3 這樣依次報 數到 m 的 士兵會被殺死出列,之後的士兵再從 1 開始報數。直到最後剩下一士兵,求這個士兵的編號。有用遞迴函式 f n,m 的返回結果是存活士兵的編號,推導出old 與 new...

c 解決約瑟夫環問題

c 解決約瑟夫環問題 約瑟夫 josephus 問題 m個人圍坐成一圈,從1開始順序編號 遊戲開始,從第乙個人開始由1到n迴圈報數 報到m的人退出圈外問 最後留下的那個人原來的序號 本題可以定義乙個容器 vector 初始化大小 元素個數 為n。容器裡元素的值標識該人是否出局,1在圈內,0出局。值為...