2013-07-07 24 views
2

我試圖找到一種方法來創建切換行和列的數組副本。
我想通過設置陰影數組指向原始數組的指針,使item [2 1]指向item [1 2]。創建具有切換行和列的數組的陰影陣列

使用指針會產生這樣的效果,即在更改原始數組時,陰影數組也會反映該更改。

到目前爲止,我想出了陣列中每個項目都使用長度爲1的位移數組。
它的作品,但結果是陣列的數組。
我的問題是,有沒有更好的方法來做到這一點?
是否有一種方法可以通過陰影數組使用setf來設置原始數組中的值?

我迄今爲止代碼:

(defun shadow-column-array (array) 
    (let* ((colsize (second (array-dimensions array))) 
     (rowsize (first (array-dimensions array))) 
     (b (make-array (list colsize rowsize)))) 
    (dotimes (i rowsize b) 
     (dotimes (j colsize) 

     (setf (aref b j i) 
       (make-array 1 
          :displaced-to array 
          :displaced-index-offset (+ (* i rowsize) j))))))) 

一些輸出:

*a* => #2A((0.0 0.1 0.2) (1.0 1.1 1.2) (2.0 2.1 2.2)) 

(setq b (shadow-column-array (*a*)) 

*b* => #2A((#(0.0) #(1.0) #(2.0)) (#(0.1) #(1.1) #(2.1)) (#(0.2) #(1.2) #(2.2))) 

流離失所列的陣列現在

col1 => #(#(0.0) #(1.0) #(2.0))  
col2 => #(#(0.1) #(1.1) #(2.1)) 
col3 => #(#(0.2) #(1.2) #(2.2)) 

回答

0

是我想也許還可以利用兩個數組,並設置兩個時我改變了內容。你可以很容易地編寫一個SETF函數。如果它應該看起來像用戶的單個數據結構,那麼我還會使用帶有陣列插槽的CLOS實例。

3

使原始數組的每個元素都成爲'引用單元格'。然後用相同的單元格創建一個陰影數組,但元素相反。更改單元格中的值將更改數組內容。

(defun make-celled-array (m n init) 
    (let ((array (make-array (list m n)))) 
    (dotimes (i m) 
     (dotimes (j n) 
     (setf (aref array i j) (list init)))) ; (list init) makes a 'cell' 
    array)) 
(defun celled-array-ref (array m n) 
    (car (aref array m n))) 
(defsetf celled-array-ref (array m n) (val) 
    `(setf (car (aref ,array ,m ,n)) ,val)) 

(defun shadow-celled-array (ca) 
    (let ((m (array-dimension ca 1)) ; swapped 
     (n (array-dimension ca 0))) 
    (let ((array (make-array (list m n)))) 
     (dotimes (i m) 
     (dotimes (j n) 
      (setf (aref array i j) (aref ca j i)))) ; swapped 
     array))) 

用途:

* (defvar a1 (make-celled-array 2 4 1)) 
A1 

* (setf (celled-array-ref a1 0 3) 10) 
10 

* a1 
#2A(((1) (1) (1) (10)) ((1) (1) (1) (1))) 

* (defvar a2 (shadow-celled-array a1)) 
A2 

* a2 
#2A(((1) (1)) ((1) (1)) ((1) (1)) ((10) (1))) 

* (celled-array-ref a2 3 0) 
10 

* (setf (celled-array-ref a2 3 0) 100) 
100 

* (celled-array-ref a1 0 3) 
100