方案

2016-07-26 58 views
1

我想實現這樣的方案很簡單圖形簡單的圖形表示:名單方案

'((node1 '(node2 node3)) (node2 '()) (node3 '())) 

名單,但現在我需要在圖形列表存儲在一個變量。 我嘗試使用定義

(define graph '()) 

,然後使用此過程增加更多的節點列表。

(define (add-node name children) (list graph (list name children))) 

它按預期工作:

(add-node 1 '(2 3)) 

返回:「(()(1(2 3)))

問題是我未能更新與新添加的圖形節點。 嘗試重新定義圖形會導致「已定義的錯誤」,試圖使用let/let!造成「無法修改恆定錯誤」

任何幫助或建議將不勝感激。

編輯: 感謝@奧斯卡·洛佩斯

我想出了我的問題的解決方案。 我不是一個方案大師,但這裏是我的代碼(ATLEAST工程:))

;Define the empty graph 
(define graph '()) 

; Graph mutator. All modify operations use this procedure 
(define (modify-graph newGraph) 
(set! graph newGraph) 
    graph) 

; Adds a node to the graph (name '(chidren)) (add-node 1 '(2 3)) 
(define (add-node name children) 
    (define (add-node-helper name children graph) 
    (cons (list name children) graph)) 
    (modify-graph (add-node-helper name children graph))) 

; Generic procedure which removes elements from list that match certain condition 
(define (remove-element elements condition?) 
    (cond ((empty? elements) elements) 
     ((condition? (car elements)) (remove-element (cdr elements) condition?)) 
     (else (cons (car elements) (remove-element (cdr elements) condition?)))) 
) 


; Removes a node, and all references to it. 
(define (remove name) 
    (define (remove-node name) 
    (define (condition? element) 
    (eq? (car element) name)) 
    (remove-element graph condition?)) 

    (define (remove-all-refs name) 
    (define (remove-child name node) 
     (define (condition? element) 
     (eq? name element)) 
     (cons (car node) (list (remove-element (cadr node) condition?)))) 

    (define (remove-all-refs-helper name graph) 
     (cond ((empty? graph) graph) 
      (else (cons (remove-child name (car graph)) (remove-all-refs-helper name (cdr graph)))))) 

    (remove-all-refs-helper name graph)) 

    (modify-graph (remove-node name)) 
    (modify-graph (remove-all-refs name)) 
) 

最終的結果是:

(add-node 1 '(2 3)) 
(add-node 3 '(5 6)) 
(add-node 2 '(7 8 9 10 11)) 
> graph ;-> '((2 (7 8 9 10 11)) (3 (5 6)) (1 (2 3))) 

也刪除節點刪除給定節點的所有引用。

回答

3

您應該避免突變全局定義的數據,並且您的add-node過程看起來不正確(圖形將在每次調用時嵌套在列表中)。我建議如下:

(define (add-node name children graph) 
    (cons (list name children) graph)) 

即:將圖形作爲參數傳遞,並返回帶有新添加節點的列表。然後遞歸通過修改圖形周圍(首選)或修改其值的變量(推薦):

; good idea 
(procedure-that-modifies-graph (add-node name children graph)) 

; not recommended 
(let ((graph '())) 
    (set! graph (procedure-that-modifies graph (add-node name children)))) 

在方案中,最推薦的方式是避免變異的變量,如果有什麼需要改變你創建一個新的包含修改的對象(本例中爲節點列表)並將其傳遞給將其作爲參數接收的過程,我們可以根據需要多次執行此操作,可能以遞歸方式進行。

+0

你好,抱歉,延遲響應。我去了你的「不推薦」,因爲我覺得它對最終用戶來說更舒服。我用我提出的代碼更新了我的答案。再次感謝 :) –