2

まず第一に、私は LispWorks を使っています。位置 i < フィル ポインターに要素を挿入する調整可能な配列があるため、すべての要素を i からその位置 + 1 に移動する必要があります。私の問題は、その方法がわからず、結果として調整可能な配列が得られますが、すべての要素を別の配列にコピーする必要はありません。パフォーマンスは本当に重要です。この配列 #(0 1 2 3 4 6 7) を使用して、位置 i=5 に番号 5 を挿入する方法:

(let ((arr (make-array 7 :initial-contents (list 0 1 2 3 4 6 7) 
                     :adjustable T :fill-pointer 7))
      (i 5)) 
    (concatenate 'vector (subseq arr 0 i)
                         (make-array 1 :initial-contents '(5))
                         (subseq arr i (fill-pointer arr))))

LispWorks がすべての要素を結果の配列に内部的にコピーしているかどうかはわかりませんが、目的の配列が得られますが、調整はできず、フィルポインターもありません。何かアイデア?

4

2 に答える 2

3

まず第一に、あなたのコードは conses が多すぎます。

これは可能な限りコンスを少なくしたバージョンです:

(defun insert-into-array (vector value position)
  (vector-push-extend value vector) ; ensure that the array is large enough
  ;; shift the end of the array right
  (loop for i from (1- (length vector)) downto (1+ position) do
      (setf (aref vector i) (aref vector (1- i))))
  (setf (aref vector position) value) ; insert value into the right place
  vector)
(insert-into-array (make-array 9 :initial-contents '(0 1 2 3 4 6 7 8 9) 
                                 :adjustable T :fill-pointer 9) 5 5)
==> #(0 1 2 3 4 5 6 7 8 9)

最悪の場合、これは代入を行うことに注意してくださいN。したがって、セットアップで挿入が一般的な操作であり、ランダム アクセスが必要ない場合は、配列の代わりにリンク リストを検討することをお勧めします。

編集: を忘れていreplaceたため、ループが不要になります:

(defun insert-into-array (vector value position)
  (replace vector vector :start2 position :start1 (1+ position) 
           :end2 (vector-push-extend value vector))
  (setf (aref vector position) value) 
  vector)
于 2013-06-09T13:23:41.587 に答える