2

私はこのようなものを実装する必要があります:

(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))

ループマクロでこのようなことをすることは可能ですか?別の関数として実装することもできますが、表現力を高めるためにループまたはループ状のマクロを使用したいと思います。おそらく、この場合のためだけに単純なループのようなマクロを定義する方法がありますか?

4

3 に答える 3

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))
于 2013-01-25T23:37:19.770 に答える
2

LOOPCommonLisp標準で定義されているように拡張可能ではありません。

私は通常の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マクロよりも強力で、拡張性もあります。

于 2013-01-25T23:37:45.183 に答える
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)))
于 2013-01-26T08:43:25.277 に答える