LISP 条件编程
LISP conditional programming
我正在尝试编写一个非常简单的程序,但虽然我无法理解,但请帮忙
假设我们有 10 个圆圈,每个圆圈都有 X、Y、Z、r
该程序将采用这些变量(x、y、z、r)并找出哪一对圆可以构成一个圆柱体(换句话说,哪些圆具有相同的 x、y、r(但不相同的 z))
我应该使用什么样的命令? "cond if if....else 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 那样接受它...
当然,您可以根据需要嵌套 cond
s:
(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))
)
仔细观察,你会发现所有的s表达式,从(= a b)
开始到(< a b)
和(print 'a<b)
都在相同的 括号组:分隔外部 cond
的括号。因此,所有这些表达式都是第一种情况的一部分,因此您只有一种情况。
你要的是这个:
(cond ((= a b)
(cond ((= b c)
(print 'a=b=c))))
(> a b) (print 'a>b)
(< a b) (print 'a<b))
仔细看缩进!
但是解决您最初的问题:您应该尝试在您的代码中表达您想要编程的想法。你写了 "circles" 之类的东西,但是你的代码没有表达任何这些(a
、b
、c
等等很少是好名字)。
首先将您对圆的想法写入代码:
(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
s,事实上,明确地使用 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,因为写了很多本质上没有必要的东西,我们需要重复很多次。有很多工具(defclass
、defstruct
、访问器函数、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
,因为只有一个 case 的 cond
并不是很好的代码风格:只有当你有两个以上的分支时才使用它(例如两个分支使用 if
).
希望对您有所帮助。
(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 没有值
我正在尝试编写一个非常简单的程序,但虽然我无法理解,但请帮忙 假设我们有 10 个圆圈,每个圆圈都有 X、Y、Z、r 该程序将采用这些变量(x、y、z、r)并找出哪一对圆可以构成一个圆柱体(换句话说,哪些圆具有相同的 x、y、r(但不相同的 z)) 我应该使用什么样的命令? "cond if if....else 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 那样接受它...
当然,您可以根据需要嵌套 cond
s:
(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))
)
仔细观察,你会发现所有的s表达式,从(= a b)
开始到(< a b)
和(print 'a<b)
都在相同的 括号组:分隔外部 cond
的括号。因此,所有这些表达式都是第一种情况的一部分,因此您只有一种情况。
你要的是这个:
(cond ((= a b)
(cond ((= b c)
(print 'a=b=c))))
(> a b) (print 'a>b)
(< a b) (print 'a<b))
仔细看缩进!
但是解决您最初的问题:您应该尝试在您的代码中表达您想要编程的想法。你写了 "circles" 之类的东西,但是你的代码没有表达任何这些(a
、b
、c
等等很少是好名字)。
首先将您对圆的想法写入代码:
(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
s,事实上,明确地使用 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,因为写了很多本质上没有必要的东西,我们需要重复很多次。有很多工具(defclass
、defstruct
、访问器函数、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
,因为只有一个 case 的 cond
并不是很好的代码风格:只有当你有两个以上的分支时才使用它(例如两个分支使用 if
).
希望对您有所帮助。
(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 没有值