2013-05-20 71 views
1

我在改造這樣的載體問題:方案/球拍矢量在矢量變換

#(#(1 2 3)#(1 2 3)#(1 2 3)#(1 2 3)#(1 2 3))) 

進入一個這樣的:

#(#(1 1 1 1 1) #(2 2 2 2 2) #(3 3 3 3 3)) 

我寫了一段測試代碼,但輸出錯誤。我進入調試器,我想我知道哪一行代碼會導致問題。我似乎無法找到一種方法使其工作。任何幫助是極大的讚賞。

(define (test) 
    (let* ((table #(#(1 2 3)#(1 2 3)#(1 2 3)#(1 2 3)#(1 2 3))) 
     (counter 5) 
     (size 3) 
     (new-table (make-vector size (make-vector counter #f)))) 

    (let loop ((sc 0) 
       (cc 0)) 
     (when (not (= cc counter)) 
     (if (not (= sc size)) 
      (begin (vector-set! (vector-ref new-table sc) cc (vector-ref (vector-ref table cc) sc)) 
        (loop (+ 1 sc) cc)) 
      (loop 0 (+ 1 cc))))) 
    (display new-table))) 

> (test) 
#(#(3 3 3 3 3) #(3 3 3 3 3) #(3 3 3 3 3)) 
+2

順便說一句,在「轉型」你表演的是[轉](http://en.wikipedia.org/wiki /轉置)實現爲向量的矢量 –

回答

4

有這部分的問題:

(make-vector size (make-vector counter #f)) 

爲什麼?因爲你正在複製完全相同的矢量,所有關閉new-table的位置,所以無論何時更新一個值,它都會同時更改所有這些值。這很容易看出:

(define new-table (make-vector 3 (make-vector 3 #f))) 
(vector-set! (vector-ref new-table 0) 0 42) ; we modify a single position ... 
new-table 
=> '#(#(42 #f #f) #(42 #f #f) #(42 #f #f)) ; ... but all of them changed! 

您必須在開始時初始化向量;您的代碼的固定版本將如下所示:

(let* ((table '#(#(1 2 3) #(1 2 3) #(1 2 3) #(1 2 3) #(1 2 3))) 
     (counter (vector-length table)) 
     (size (vector-length (vector-ref table 0))) 
     (new-table (make-vector size))) 
    ; initialization 
    (let loop ((i 0)) 
    (when (< i size) 
     (vector-set! new-table i (make-vector counter)) 
     (loop (+ i 1)))) 
    (let loop ((sc 0) 
      (cc 0)) 
    (when (not (= cc counter)) 
     (if (not (= sc size)) 
      (begin 
      (vector-set! (vector-ref new-table sc) cc 
         (vector-ref (vector-ref table cc) sc)) 
      (loop (+ 1 sc) cc)) 
      (loop 0 (+ 1 cc)))) 
    new-table)) 

但是,上述解決方案很難理解。幸運的是,這似乎是使用球拍的Iterations and Comprehensions一個很好的問題,所以您不必到大約明確地擔心使用迭代遞推,從而導致更清晰的解決方案:

(let* ((table '#(#(1 2 3) #(1 2 3) #(1 2 3) #(1 2 3) #(1 2 3))) 
     (counter (vector-length table)) 
     (size (vector-length (vector-ref table 0))) 
     (new-table (make-vector size))) 
    (for ([sc (in-range size)]) 
    (vector-set! new-table sc (make-vector counter)) ; initialization 
    (for ([cc (in-range counter)]) 
     (vector-set! (vector-ref new-table sc) cc 
        (vector-ref (vector-ref table cc) sc)))) 
    new-table) 

無論哪種方式,如預期的輸出:

=> '#(#(1 1 1 1 1) #(2 2 2 2 2) #(3 3 3 3 3)) 

注:正因爲如此,這是一個過程式編程風格的解決方案,修改就地新的載體和具有可快速,高效的優點(它不會創造更多的載體或列出超出嚴格必要的),但事實被告知,這是不平常的解決方案中的問題的方法。對於函數式編程風格的解決方案,更多的是Scheme的精神,請參閱@ Ankur的答案。

4

您還可以使用vector-map以獲得所需的輸出:

(define table #(#(1 2 3) #(1 2 3) #(1 2 3) #(1 2 3) #(1 2 3))) 

(apply vector-map vector (vector->list table))