使用常见的lisp'求和矢量'宏

时间:2013-01-25 23:00:58

标签: loops lisp common-lisp

我需要实现这样的事情:

(loop for i from 1 to N sum (f i))

除了累积值代表数字列表,如(1 2 3) 并且它们是按元素添加的。换句话说,我想初始化求和 使用(zerov N)并使用(v +)添加后续元素:

(defun v+ (a b) (mapcar '+ a b))
(defun zerov (n) (loop for i from 1 to n collect 0))

是否可以使用循环宏执行此类操作?我可以把它作为一个实现 单独的功能,但我想使用循环或类似循环的宏来表达。 也许有一种方法可以为这种情况定义简单的类似循环的宏?

3 个答案:

答案 0 :(得分:3)

(loop with accum = (make-list n :initial-element 0)
      for i from 1 to n
    do (setq accum (v+ accum (f i)))
  finally (return accum))

答案 1 :(得分:2)

Common Lisp标准中定义的

LOOP不可扩展。

我会用正常的LOOP功能编写它:

(let ((result (zerov n)))
  (loop for i from 1 to N
        do (setf result (v+ result (f i))))
  result)

我会把它写成一个函数:

(defun sum (n f init sum)
  (let ((result (funcall init n)))
    (loop for i from 1 to n
          do (setf result (funcall sum result (funcall f i))))
    result))

如果你想要这样的功能作为循环宏的直接语言特性,那么另一种选择是ITERATE宏,它比LOOP宏更强大,并且它也是可扩展的。

答案 2 :(得分:0)

(reduce #'v+ (loop for i from 1 to n collect (f i))
        :initial-value (zerov n))

请注意,Common Lisp具有适当的“向量”(即,均匀类型的元素序列允许更紧凑的表示和有效的随机访问),所以也许,

(defun v+ (a b) (map-into a #'+ a b))
(defun zerov (n) (make-array n :initial-element 0))
(defun fn (i n) (let ((v (zerov n))) (setf (aref v i) 1) v))
(defun gn (n)
  (loop for v = (zerov n) then (v+ v (fn i n)) for i below n
        finally (return v)))
相关问题