使用嵌套列表LISP

使用嵌套列表LISP,lisp,common-lisp,nested-lists,Lisp,Common Lisp,Nested Lists,我对lisp比较陌生,对在以下上下文中使用嵌套列表的最佳方法感到好奇: 因此,我有以下功能: (defun get-p0 (points) (loop for (label x y) in points ; collect (list (if (> x y) (+ 2 3)))) collect (list (get-angle (first points) (second points)))) ) 我这样称呼它: (get-p0 '((A 5 2) (B 2 3

我对lisp比较陌生,对在以下上下文中使用嵌套列表的最佳方法感到好奇:

因此,我有以下功能:

(defun get-p0 (points)
    (loop for (label x y) in points
    ; collect (list (if (> x y) (+ 2 3))))
    collect (list (get-angle (first points) (second points))))
)
我这样称呼它:

(get-p0 '((A 5 2) (B 2 3) (C 8 9)))
我一直想做的是得到每个坐标相对于其他坐标的角度。例如,将AB、AC、BA、BC、CA、CB的角度打印出来。我得到的结果如下:

((161.56505) (161.56505) (161.56505))

那真的只是为了测试目的。虽然我真正想做的是输出最低和最左边的坐标。有什么想法吗?

不久前我做了类似的练习。这看起来对您很有用:

;; Define struct `point'
(defstruct point x y)

;; Define methods specializing on `point'
(defgeneric add (a b))

(defgeneric subtract (a b))

(defgeneric distance (a b))

(defgeneric projection (a))

(defmethod add ((this point) (that point))
  (make-point :x (max (point-x this) (point-x that))
              :y (max (point-y this) (point-y that))))

(defmethod subtract ((this point) (that point))
  (make-point :x (min (point-x this) (point-x that))
              :y (min (point-y this) (point-y that))))

(defmethod distance ((this point) (that point))
  (let ((a (add this that)) (b (subtract this that)))
    (make-point :x (- (point-x a) (point-x b))
                :y (- (point-y a) (point-y b)))))

(defmethod projection ((this point))
  (sqrt (+ (expt (point-x this) 2) (expt (point-y this) 2))))

;; Define helper functions
(defun angle (a b c)
  (acos (/ (+ (* a a) (* b b) (- (* c c))) (* 2 a b))))

(defun radian->degree (radian) (/ (* 180 radian) pi))

;; Define struct `triangle'
(defstruct triangle
  (a nil :type (or null point))
  (b nil :type (or null point))
  (c nil :type (or null point)))

;; Define methods specializing on `triangle'
(defgeneric angles-of (triangle))

(defgeneric sides-of (triangle))

(defgeneric points-of (triangle))

(defmethod points-of ((this triangle))
  (let ((result (list (triangle-a this) (triangle-b this) (triangle-c this))))
    (nconc result result)))

(defmethod sides-of ((this triangle))
  (loop for (p . rest) on (points-of this)
     for i from 0 below 3
     collect (projection (distance p (car rest))) into result
     finally (return (nconc result result))))

(defmethod angles-of ((this triangle))
  (loop for (a b c) on (sides-of this)
       for i from 0 below 3
       collect (radian->degree (angle a b c)) into result
       finally (return (nconc result result))))

;; Create some test triangle
(defvar *pythagorean-triangle*
  (make-triangle :a (make-point :x 1 :y 2)
                 :b (make-point :x 4 :y 2)
                 :c (make-point :x 4 :y 6)))

;; Finally! don't forget to
(setf *print-circle* t)
;; so you can see circular lists' content
(angles-of *pythagorean-triangle*)

#1=(90.00000265626015d0 36.86989784081561d0 53.13009995842113d0 . #1#)
我在另一篇博文中看到了一些关于表格的混乱

(loop for <list-like expression> in some-list ...)
这个类似列表的表达式通常被称为解构绑定。它是一个有限的模式匹配工具。实际上,这是一种模式,它将您在模式中定义的符号映射到您正在迭代的列表中找到的任何值


例如,1234上xy的循环将x和y绑定到1和2,然后是2,3,3,4,最后是4,nil。当然,您可以使用更多变量/您可以对模式等使用虚线列表。

您使用列表中x y z的形式正确绑定了每次迭代的值。但是,当您在下一行中进行收集时,您将从列表的开头删除值。该值在循环的计算过程中永远不会改变

您应该将代码更改为如下所示:

(defun get-p0 (points)
  (loop
      for (label x y) in points
      collect (list (get-angle x y))))

如果我正确理解了你的目标,你需要使用一个列表,比如'a2b23c889,然后返回一些东西,比如22点a的y为2,点B的x为2,这些是最低的坐标。我会做类似的事情

(loop for (_l x y) in lst
        minimizing y into min-y minimizing x into min-x
        finally (return (list min-x min-y)))

循环是一个深刻而强大的构造,因此我建议您通读,很容易忘记一个可能非常适合给定情况的指令。如果你是Lisp新手,实际上你可能想看看;当时我对那些特定的关键词一无所知。修正。