1

次のように、テスト配列という名前の次元 '(3 3 2) の配列があります。

#3A(((0 0) (0 0.1) (0 0.3)) 
    ((1 0) (1 0.1) (1 0.3))
    ((2 0) (2 0.1) (2 0.3)))

配列内の最も内側のリスト (ランク 2) はポイント座標であることに注意してください。したがって、一般的に配列は次のようになります。

#3A(((x0 y0) (x0 y1) (x0 y2)) 
    ((x1 y0) (x1 y1) (x1 y2))
    ((x2 y0) (x2 y1) (x2 y2)))

この配列内の要素を使用して、新しい配列を作成します。

この配列のすべての行 (配列ランク: 0) で、1 番目の xy 座標から 2 番目の xy 座標を、2 番目の xy 座標から 3 番目の xy 座標を減算します。したがって、基本的にパラメトリック形式で探している結果は次のとおりです。

#3A(((x0-x0 y1-y0) (x0-x0 y2-y1)) 
    ((x1-x1 y1-y0) (x1-x1 y2-y1))
    ((x2-x2 y1-y0) (x2-x2 y2-y1))

初期配列を操作するだけでこれを行う単純な直接関数または操作はありますか?

私はこれに対する直接的な操作を知らないので、最初の配列からリストを作成し:initial-contentsて新しい配列にすることを考えました。したがって、このアプローチの最初の目的は、次の初期コンテンツ リストを取得することです。

   (((x0-x0 y1-y0) (x0-x0 y2-y1)) 
    ((x1-x1 y1-y0) (x1-x1 y2-y1))
    ((x2-x2 y1-y0) (x2-x2 y2-y1))

これを行うために、2回使用するコードを考えましたdotimes(外側のループの数は行の数になり、内側のループの数は列の数になります):

(let ((result-1))
  (dotimes (n (array-dimension test-array 0) result-1)
    (setq result-1
      (append result-1
              (let ((result-2))
                (dotimes (m (1- (array-dimension test-array 1)) result-2)
                  (setq result-2
                    (append result-2 
                            (list (- (aref test-array n (1+ m) 0)
                                     (aref test-array n m 0))
                                  (- (aref test-array n (1+ m) 1)
                                     (aref test-array n m 1)))))))))))

しかし、これには質問のタイトルでもある1つの問題があります。明らかに、この「パラメトリック」な方法 (n & m を使用) に入力を与える方法arefは、CL では評価されません。(aref test-array n m 0)

なぜそのような問題があるのですか?ループ内で aref を使用する他の方法を考えることができますか、または別のアプローチで :initial-contents リストを作成できますか?

私が持っている実際の初期配列の次元は (21 16 2) であり、すべての xy 座標は互いに異なるため、これは私の実際の質問の比較的単純な形式であることに注意してください。

回答をいただければ幸いです...

4

1 に答える 1

3

コメントで気づいたように、引数を 1 増やして返す関数は1+, ではありません+1(これは関数名ではなく定数1です)。

ここで構築する必要はないと思います:initial-contents。なぜなら、ターゲット配列を構築して別のステップとしてループに入れるよりも簡単ではないからです。それが私がそれをする方法です:

(defparameter *test-array*
  #3A(((0 0) (0 0.1) (0 0.3)) 
      ((1 0) (1 0.1) (1 0.3))
      ((2 0) (2 0.1) (2 0.3))))

(destructuring-bind (rows cols axes) (array-dimensions *test-array*)
  (let ((result (make-array
                 (list rows (1- cols) axes)
                 :element-type (array-element-type *test-array*))))
    (dotimes (row rows result)
      (dotimes (col (1- cols))
        (dotimes (axis axes)
          (setf (aref result row col axis)
                (- (aref *test-array* row (1+ col) axis)
                   (aref *test-array* row col axis))))))))

この例をできるだけ単純にすることにしました。たとえば、配列に置き換えられたベクトルを使用するなど、代替ソリューションが可能です (これは、シーケンス関数を使用して多次元配列の断片を操作する方法です)。より複雑なケースではないにしても、このタスクには単純なアプローチをお勧めし ます。

于 2013-02-17T17:02:21.507 に答える