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函数的其中一个。