通过附加向量在方案中突变向量

时间:2013-09-04 01:23:00

标签: vector functional-programming scheme mit-scheme

我不知道Scheme中向量的底层实现,因此不确定如何编写vector-append!

原型:

(define (vector-append! vect . vects)
  ; definition here 
  )

P.S。首选使用向量列表,因为vector-ref是一个常量时间操作[src]

4 个答案:

答案 0 :(得分:5)

您无法在创建矢量后调整其大小,因此vector-append!无法实现为就地操作。您可以做的是创建一个大小等于所有子向量大小之和的新向量,其中所有子向量中的元素将一个接一个地复制。

使用vector-grow作为启动程序,并从那里开始工作。你必须使用索引来获得一个可行的解决方案。

答案 1 :(得分:2)

矢量无法调整大小。因此,无法扩展向量大小的vector-append!

答案 2 :(得分:0)

这是我的实施。抱歉评论是从现在开始,而不是在我写这个函数的时候。

另外,不要认为你可以直接改变矢量,因为它们是固定长度的。

(define (vector-append . rest)
 (letrec    
    ((all-vectors?
     (lambda (vector . rest)
          (and (vector? vector)
           (or (null? rest) 
           (apply all-vectors? rest))))) 
    (++ (lambda (x) (+ x 1)))
    (gobble-next
     (lambda (big-i small-i vec-big vec-small)
      (if (= small-i  
         (vector-length vec-small))
          'gobbled
          (begin 
        (vector-set! vec-big big-i (vector-ref vec-small small-i))
        (gobble-next (++ big-i) (++ small-i) vec-big vec-small)))))
    (helper 
     (lambda (i vector . rest) ;;the i here keeps track of the place in the new-vec 
          (if (null? rest)     ;;to start copying at
          (begin
        (gobble-next i 0 new-vec vector)
        new-vec)
          (begin
        (gobble-next i 0 new-vec vector)

        (apply helper (cons 
                (+ i (vector-length vector)) 
                rest))))))
    (new-vec (make-vector (apply length-of-vectors rest)))) ;;end of letrec
   (cond ((null? rest) 
      (error "error, no arguments to vector-append"))
     ((not (apply all-vectors? rest)) (error "arguments not all vectors"))
     ((null? (cdr rest))
      (car rest))
     (else (apply helper (cons 0 rest)))))) 

(define length-of-vectors 
  (lambda (vector . rest)
   (+ (vector-length vector)
      (if (null? rest)
      0
      (apply length-of-vectors rest)))))

答案 3 :(得分:0)

通常是'!'意味着Scheme中的破坏性操作。你没有明确表示你想要一个破坏性的实现。我会给你们两个,有点儿。首先是非破坏性版本,简单地说:

(define (vector-append! vect . vects)
  (list->vector (apply append (map vector->list (cons vect vects)))))

现在对于可变的,你需要自己的向量抽象,因为Scheme向量的长度是不可变的。不要让这分散你的注意力;如果你需要它,你需要它。

(define (my-vector . values)
  (cons 'MY-VECTOR (list->vector values)))
(define my-vector-values cdr)  ; private

(define (my-vector-ref vect index)
  (vector-ref (my-vector-values vect) index))

(define (my-vector-append! vect . vects)
  (set-cdr! vect (apply vector-append! (map my-vector-values (cons vect vects)))))

然后为你的新抽象提供一些帮助:

(define (list->my-vector list)
  (cons 'MY-VECTOR (list->vector list)))

(define (vector->my-vector vector)
  (cons 'MY-VECTOR vector) ; maybe

;; etc