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出局。值為...