#lisp
Вопрос:
Я создаю программу и лисп, и мне нужно проверить, существуют ли минусы в списке минусов, но по какой-то причине он продолжает возвращать ноль в операторе if, вот текущий код, который я использую для него.
(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)
Почему элемент(cons z (cons y nil)) возвращает ноль, даже если на первой итерации мы видим, что (1 2) существует в списке?
Редактировать:
В настоящее время, даже если это правда, он возвращает ноль, почему это должно быть так, учитывая следующий код?
(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) )
Комментарии:
1. Вы создаете новые ограничения , позвонив
cons
, они не могут бытьeql
связаны с ограничениями в списке. Воспользуйсяequal
2. Вы не используете
then
при использованииif
макроса.3. Единственный код
if
, содержащийся в нем, закомментирован. Покажите код с проблемой, а не код, в котором нет ошибки.4. К вашему сведению,
(cons x (cons y nil))
обычно пишется как(list x y)
5. @Barmar Обе поправки к изменению eql на равный и на (список x y) исправили это!
Ответ №1:
findEdge
ничего не возвращает. Звонит return-true
и return-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))