在算法中&數據II,我們用這些來「退出」或從(長)函數
例如「迴歸」的BFS algorthm穿越樹木是這樣實現的所有時間:
(define (BFS graph root-discovered node-discovered edge-discovered edge-bumped . nodes)
(define visited (make-vector (graph.order graph) #f))
(define q (queue.new))
(define exit())
(define (BFS-tree node)
(if (node-discovered node)
(exit node))
(graph.map-edges
graph
node
(lambda (node2)
(cond ((not (vector-ref visited node2))
(when (edge-discovered node node2)
(vector-set! visited node2 #t)
(queue.enqueue! q node2)))
(else
(edge-bumped node node2)))))
(if (not (queue.empty? q))
(BFS-tree (queue.serve! q))))
(call-with-current-continuation
(lambda (my-future)
(set! exit my-future)
(cond ((null? nodes)
(graph.map-nodes
graph
(lambda (node)
(when (not (vector-ref visited node))
(vector-set! visited node #t)
(root-discovered node)
(BFS-tree node)))))
(else
(let loop-nodes
((node-list (car nodes)))
(vector-set! visited (car node-list) #t)
(root-discovered (car node-list))
(BFS-tree (car node-list))
(if (not (null? (cdr node-list)))
(loop-nodes (cdr node-list)))))))))
正如你所看到的算法,當節點發現的函數返回true,將退出:
(if (node-discovered node)
(exit node))
功能也將給予「回報值「:‘節點’
爲什麼函數退出,是因爲這句話的:
(call-with-current-continuation
(lambda (my-future)
(set! exit my-future)
當我們使用退出,它會回到狀態執行之前,清空調用堆棧和返回你給它的價值。
所以基本上,撥打-CC使用(在這裏)跳出一個遞歸函數,而不是等待整個遞歸本身結束
(做大量的計算工作時,它可以是相當昂貴)
另一個較小的例子做與呼叫-CC相同的:
(define (connected? g node1 node2)
(define visited (make-vector (graph.order g) #f))
(define return())
(define (connected-rec x y)
(if (eq? x y)
(return #t))
(vector-set! visited x #t)
(graph.map-edges g
x
(lambda (t)
(if (not (vector-ref visited t))
(connected-rec t y)))))
(call-with-current-continuation
(lambda (future)
(set! return future)
(connected-rec node1 node2)
(return #f))))
是的!我正在尋找代碼示例。 – 2008-09-19 20:51:54