【问题标题】:Checking If Cons exist in list of Cons检查 Cons 列表中是否存在 Cons
【发布时间】:2021-12-27 01:09:30
【问题描述】:

我正在构建一个程序和 lisp,需要检查一个 Cons 是否存在于一个 cons 列表中,但由于某种原因,它在 if 语句中一直返回 nil,这是我正在使用的当前代码。

(defun countVertexTriangles (graph numOfVertices)
    (findTriangle graph numOfVertices)
)

(defun findTriangle(graph numOfVertices)
    (loop for (x y) in graph do
            (loop for z from 1 to numOfVertices do
                (write graph)
                (terpri)
                (write (cons z (cons y nil)))
                (terpri)
                (write (cons z (cons x nil)))
                (terpri)
                ; (if (AND (member (cons z (cons y nil)) graph) (member (cons z (cons x nil)) graph))
                ;     then (write (cons y z))
                ; )
            )
        (terpri)
    )
)

; (defun findEdge(graph edge)
;     (loop for x in graph do
;         (write x)
;         (write edge)
;         (if (eql x edge)
;             (write "A")
;             (write "B")
;         )
;     )
; )

(defun testFunct ()
    (setf g1 '((1 2)(2 3)(1 3)(2 4)(3 4)(4 5)(3 5)))
    (countVertexTriangles g1 5)
)

(testFunct)

即使在第一次迭代中我们可以看到 (1 2) 存在于列表中,为什么 member(cons z (cons y nil)) 返回 nil?

编辑:

目前即使它为 true 它返回 nil,为什么会出现以下代码?

(defun countVertexTriangles (graph numOfVertices)
    (findTriangle graph numOfVertices)
)

(defun findTriangle(graph numOfVertices)
    (loop for (x y) in graph do
            (loop for z from 1 to numOfVertices do
                ; (write graph)
                ; (terpri)
                ; (write (list z y ))
                ; (terpri)
                (write (findEdge graph (list z y)))
                (terpri)
                ; (if (AND (member (list z x) graph) (member (list z x ) graph))
                ;     then (write "TEST")
                ; )
            )
        (terpri)
    )
)

(defun findEdge(graph edge)
    (loop for x in graph do
        (if (equal x edge)
            (return-true)
            (return-false)
        )
    )
)

(defun return-true ()
   t)

(defun return-false ()
   nil)

(defun testFunct ()
    (setf g1 '((1 2)(2 3)(1 3)(2 4)(3 4)(4 5)(3 5)))
    (countVertexTriangles g1 5)
)

【问题讨论】:

  • 您正在通过调用cons 创建新的conses,它们不可能是eql 到列表中的conses。使用equal
  • 使用if宏时不要使用then
  • 唯一带有if的代码被注释掉了。显示有问题的代码,而不是没有错误的代码。
  • 仅供参考,(cons x (cons y nil)) 通常写作(list x y)
  • @Barmar 将 eql 更改为 equal 和 (list x y) 的两个更正都修复了它!

标签: lisp


【解决方案1】:

findEdge 不返回任何内容。调用return-truereturn-false 不会从findEdge 返回。在找到匹配项之前,您也不应该返回。

(defun findEdge(graph edge)
    (loop for x in graph do
        (if (equal x edge)
            (return-from findEdge (return-true))
        )
    )
    (return-false)
)

这可以简化为:

(defun findEdge (graph edge) 
  (member edge findEdge :test #'equal))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-29
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多