【问题标题】:Simple graph representation in SchemeScheme中的简单图形表示
【发布时间】:2016-07-26 14:10:08
【问题描述】:

我正在尝试在 Scheme 中实现非常简单的图形,如下所示:

'( (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!导致“无法修改常量错误”

任何帮助或建议将不胜感激。

编辑: 感谢@Óscar López

我想出了解决问题的方法。 我不是计划大师,但这是我的代码(至少它有效:))

;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)))

删除节点也会删除对给定节点的所有引用。

【问题讨论】:

    标签: variables graph scheme


    【解决方案1】:

    您应该避免改变全局定义的数据,并且您的 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))))
    

    在 Scheme 中,推荐的样式是避免改变变量,如果需要更改某些内容,则创建一个包含修改的新对象(在本例中为节点列表)并将其传递给接收它作为参数,我们可以根据需要多次执行此操作,可能以递归方式。

    【讨论】:

    • 您好,很抱歉回复延迟。我选择了您的“不推荐”,因为我觉得它对最终用户来说更舒服。我已经用我想出的代码更新了我的答案。再次感谢:)
    猜你喜欢
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 2012-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    相关资源
    最近更新 更多