In Algo & Daten II haben wir diese alle Zeiten „exit“ oder „Rückkehr“ von einer (langen) Funktion
zum Beispiel des BFS algorthm Bäume zu durchqueren mit wie dies umgesetzt wurde:
(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)))))))))
Wie Sie den Algorithmus sehen beendet, wenn der Knoten entdeckt Funktion true zurückgibt:
(if (node-discovered node)
(exit node))
die Funktion wird auch eine „Rückkehr geben Wert ":‚Knoten‘
warum die Funktion beendet wird, ist diese Aussage wegen:
(call-with-current-continuation
(lambda (my-future)
(set! exit my-future)
wenn wir Exit verwenden, wird es vor der Ausführung in den Zustand zurück, den Anruf-Stapel Entleerung und gib den Wert zurück, den du ihm gegeben hast.
Also im Grunde, Call-cc verwendet wird (hier) aus einer rekursiven Funktion zu springen, anstatt für die gesamte Rekursion des Wartens von selbst zu beenden (was sehr teuer sein kann, wenn eine Menge Rechenarbeit tun)
ein weiteres kleineres Beispiel das gleiche mit Call-cc tun:
(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))))
Ja! Ich suche jedoch nach Codebeispielen. –