2013-05-20 48 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))