Lisp,计算奇数
我如何定义一个数字和字母的列表,却只对列表中的奇数求和Lisp,计算奇数,lisp,common-lisp,Lisp,Common Lisp,我如何定义一个数字和字母的列表,却只对列表中的奇数求和 (oddsum '(3 6 c 5 82 29 e g) ) => 37 使用循环: (loop for ... in ... when ... sum ...) 对于高阶函数: (reduce #'+ (remove-if-not (lambda (e) ...) ...)) 单个reduce也可以工作。最简单的方法可能是只使用reduce和一个helper函数: (defun sum-only-
(oddsum '(3 6 c 5 82 29 e g) ) => 37
使用循环:
(loop for ... in ...
when ...
sum ...)
对于高阶函数:
(reduce #'+ (remove-if-not (lambda (e) ...) ...))
单个reduce也可以工作。最简单的方法可能是只使用
reduce
和一个helper函数:
(defun sum-only-odd-numbers (a b)
(+ a ;; Previous version checked for oddness here, that is incorrect
(if (and (integerp b) (oddp b)) b 0))
(reduce #'sum-only-odd-numbers ... :initial-value 0)
如果你是一个绝对的初学者,也许你还没有学习过很多特殊的形式,但是我认为你可以知道
如果一个,它的语法是(如果COND,那么ELSE)
。。。当然,您必须知道defun
使用defun
和if
我们从递归函数的定义开始,mysum
,它对一系列数字求和,即lon
:(defun mysum(lon)…
递归实现意味着我们希望(使用+
)列表的第一个元素(car lon)
,与列表剩余部分的总和(mysum(cadr lon))
:(+(car lon)(mysum(cadr lon))
-如果有第一个元素,当然。。。因此,我们检查列表是否为非空,(如果lon…
,后面是我们已经讨论过的然后是子句,最后是ELSE
子句,其值必须是空列表中的值之和,即0
,因此(+最后一个值(mysum empty list))
->最后一个值
(defun mysum (lon)
(if lon
(+ (car lon) (mysum (cdr lon)))
0))
因此,我们定义了一个非常简单的函数,因为它所操作的列表是齐次的,对于非齐次的,在引入额外的奇数后,我们必须更加小心,如果car
不是奇数,我们必须将剩余部分的和求和为0
,如果car
是奇数
(defun oddsum (mixlist)
(if mixlist
(+ (if (and (integerp (car mixlist)) (oddp (car mixlist)))
(car mixlist)
0)
(oddsum (cdr mixlist)))
0))
你尝试过什么?你应该展示你的尝试,并问一个更具体的问题,关于你被困在哪里。我建议integraerp
而不是numberp
,因为oddp
应用于实数时说值…不是整数类型a
是累加器;你不应该检查它是否是奇数。Otherwise(减少“仅和奇数”(1 3 5))
=>5
,因为四不是奇数。虽然你必须检查第一个数字是否是奇数,但这种方法并不能很好地解决问题。与其添加创建一个特殊的加法函数,为什么不使用一个键函数,将奇数整数取为自身,将其他所有整数取为0?例如,(reduce'+list:key(λ(x)(如果(和(整数x)(oddp x))x 0)))
。这样可以使逻辑的重要部分在还原站点上保持可见。@JoshuaTaylor也可以。在defun
中定义某些东西有一个小小的理由,这是因为如果需要调试东西,跟踪起来要容易得多。在这种情况下,使用外部定义的su可能完全可以m-函数,一个外部定义的键函数,或在reduce调用中作为lambda函数的其中一个。