【问题标题】:Mutate vector in scheme by appending vectors通过附加向量来改变方案中的向量
【发布时间】:2013-09-04 01:22:59
【问题描述】:

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

原型:

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

附:首选使用向量而不是列表,因为vector-ref 是一个常数时间操作[src]

【问题讨论】:

    标签: vector functional-programming scheme mit-scheme


    【解决方案1】:

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

    使用vector-grow 作为起始过程,然后从那里开始工作。您必须对索引进行一些操作才能获得有效的解决方案。

    【讨论】:

      【解决方案2】:

      矢量不可调整大小。所以扩展向量大小的vector-append! 是不可能的。

      【讨论】:

        【解决方案3】:

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

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

        (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)))))
        

        【讨论】:

          【解决方案4】:

          通常是一个“!”意味着 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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-10-25
            • 1970-01-01
            • 2011-08-11
            • 1970-01-01
            • 2013-08-11
            • 1970-01-01
            相关资源
            最近更新 更多