莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理
              sicp的習(xí)題3.22,也就是以消息傳遞的風(fēng)格重新實(shí)現(xiàn)隊(duì)列,我的解答如下:

          (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完全可以模擬單向循環(huán)鏈表,整整第三章都在講引入賦值帶來的影響,而我卻視而不見。在引入了改變函數(shù)后,數(shù)據(jù)對象已經(jīng)具有OO的性質(zhì),模擬鏈表、隊(duì)列、table都變的易如反掌。首先,模擬節(jié)點(diǎn)對象,節(jié)點(diǎn)是一個序?qū)Γó?dāng)前節(jié)點(diǎn)編號和下一個節(jié)點(diǎn):
          (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))

              有了節(jié)點(diǎn),實(shí)現(xiàn)了下單向循環(huán)鏈表:
          (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個元素的環(huán)形鏈表,比如(make-cycle-list 8)的結(jié)果如下
          #0=(1 2 3 4 5 6 7 8 . #0#)
              Drscheme形象地展示了這是一個循環(huán)的鏈表。那么約瑟夫環(huán)的問題就簡單了:
          (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))
                       ((
          = 1 i)
                        (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節(jié)點(diǎn)開始計數(shù),每到m,就將當(dāng)前節(jié)點(diǎn)刪除(通過將前一個節(jié)點(diǎn)的next-node設(shè)置為current的下一個節(jié)點(diǎn)),最后剩下的節(jié)點(diǎn)的編號就是答案。
          主站蜘蛛池模板: 迁西县| 桐庐县| 皋兰县| 桦南县| 陵水| 鱼台县| 葫芦岛市| 濉溪县| 泽普县| 河北省| 浦江县| 兰考县| 乐至县| 临夏县| 任丘市| 墨江| 深州市| 尖扎县| 都江堰市| 渝中区| 东乡县| 长丰县| 沁源县| 临沧市| 永顺县| 常州市| 南木林县| 涪陵区| 保定市| 大关县| 泗阳县| 甘德县| 昌图县| 泾阳县| 清河县| 枞阳县| 崇仁县| 郁南县| 临夏县| 四子王旗| 福建省|