LISP条件编程

时间:2015-11-15 21:40:49

标签: lisp common-lisp

我正在尝试编写一个非常简单的程序但是我无法弄清楚请帮助 假设我们有10个圆圈,每个圆圈都有X,Y,Z,r 程序将采用这些变量(x,y,z,r)并找出哪一对圆可以形成一个圆柱(换句话说哪个圆具有相同的x,y,r(但不是相同的z)) 我应该使用什么样的命令? " cond if if else,if if"

这是第一个代码:

(setq a 10)
(setq b 10)
(setq c 11)
(setq d 12)
(cond ((= a b) (cond ( (= b c) (print 'a=b=c)  )  )
(> a b) (print 'a>b)
(< a b) (print 'a<b))
)

我试图在另一个COND中使用COND作为动作,所以我可以搜索数字,如果它们是相同但似乎lisp不接受它像C ...

2 个答案:

答案 0 :(得分:1)

当然,你可以尽可能深地嵌套cond

(defun funny-compare (a b c)
  (cond ((= a b)
         (cond ((= a c) 'all-equal)
               (t 'only-two-equal)))
        ((< a b) 'less)
        ((> a b) 'greater)))

以下是一些例子:

CL-USER> (funny-compare 1 1 1)
;;=> ALL-EQUAL
CL-USER> (funny-compare 1 1 2)
;;=> ONLY-TWO-EQUAL
CL-USER> (funny-compare 1 2 2)
;;=> LESS
CL-USER> (funny-compare 2 1 2)
;;=> GREATER

您只需要将相应的条款放入正确的cond。自动缩进(以及匹配的括号和一些其他视觉辅助)使这非常简单。使用上面给出的代码并让emacs格式化它给我:

(cond ((= a b) (cond ( (= b c) (print 'a=b=c)  )  )
       (> a b) (print 'a>b)
       (< a b) (print 'a<b))
      )

仔细观察,您可以看到所有以(= a b)开头至(< a b)(print 'a<b)的s表达式都在相同的括号中:界定外cond案例的那个。因此,所有这些表达式都是第一种情况的一部分,因此您只有一个案例。

你想要的是这个:

(cond ((= a b)
       (cond ((= b c)
              (print 'a=b=c))))
      (> a b) (print 'a>b)
      (< a b) (print 'a<b))

仔细看看缩进!

但接近原来的问题:您应该尝试在代码中表达您想要编写的想法。你写的是关于“圈子”等等,但是你的代码没有表达任何这些(abc,而且很少有好名字。)

首先将您的圆圈想法放入代码中:

(defun make-circle (x y z r)
  (list x y z r))
(defun circle-x (circle)
  (first circle))
(defun circle-y (circle)
  (second circle))
(defun circle-z (circle)
  (third circle))
(defun circle-radius (circle)
  (nth 3 circle))

然后,您要检查的是多个独立条件。您不需要多个cond,事实上,使用and明确表达更好:

(cond ((and (= (circle-x one) (circle-x other))
            (= (circle-y one) (circle-y other))
            (= (circle-radius one) (circle-radius other))
            (not (= (circle-z one) (circle-z other))))
       'planar-not-same-but-on-axis-parallel-to-z))

请注意,这不是惯用的lisp,因为编写的内容很多,实际上是不必要的,我们需要重复很多。有许多工具(defclassdefstruct,访问者函数,with-slots,...)可用于缩短此范围。由于列表的强大功能,我们甚至可以摆脱=

的重复使用
(flet ((extract (circle)
         (list (circle-x circle)
               (circle-y circle)
               (circle-radius))))
  (when (and (every #'= (extract one) (extract other))
             (not (= (circle-z one) (circle-z other))))
    'planaer-not-same-but-on-axis-parallel-to-z))

请注意,我也摆脱了cond,因为单个案例的cond并不是完全好的代码样式:只有当你有两个以上的分支时才使用它(对于两个分支)使用if)。

我希望这会对你有所帮助。

答案 1 :(得分:0)

(defun make-circle (x1 y1 z1 r1)
(list x1 y1 z1 r1))
(defun circle-x (circle)
(first (make-circle x1 y1 z1 r1)))
(defun circle-y (x1 y1 z1 r1)
(second (make-circle x1 y1 z1 r1)))
(defun circle-z (x1 y1 z1 r1)
(third (make-circle x1 y1 z1 r1)))
(defun circle-radius (x1 y1 z1 r1)
(nth 3 (make-circle x1 y1 z1 r1)))
(cond ((and (= (circle-x 1 ) (circle-x 5 6 7 8))
        (= (circle-y one) (circle-y other))
        (= (circle-radius one) (circle-radius other))
        (not (= (circle-z one) (circle-z other))))
   'planar-not-same-but-on-axis-parallel-to-z))

这是你的代码我做了一点改变,但是我使用的在线编译器一直出错:CIRCLE-X:变量X1没有值