从prime-sieve函数返回向量(固定长度数组)并稍后将其转换为列表

时间:2015-08-14 23:03:57

标签: scheme

我找到了一个prime-sieve函数,它使用了Eratosthenes的Sieve来计算第一个n素数。该方法基于Donald Knuth的算法,我从here复制了它:

; http://community.schemewiki.org/?sieve-of-eratosthenes
(define (prime-sieve n) 
  (let ((pvector (make-vector (+ 1 n) #t))) ; if slot k then 2k+1 is a prime 
    (let loop ((p 3) ; Maintains invariant p = 2j + 1 
               (q 4) ; Maintains invariant q = 2j + 2jj 
               (j 1) 
               (k '()) 
               (vec pvector)) 
      (letrec ((lp (lambda (p q j k vec) 
                     (loop (+ 2 p) 
                           (+ q (- (* 2 (+ 2 p)) 2)) 
                           (+ 1 j) 
                           k 
                           vec))) 
               (eradicate (lambda (q p vec) 
                            (if (<= q n) 
                                (begin (vector-set! vec q #f) 
                                       (eradicate (+ q p) p vec)) 
                                vec)))) 
        (if (<= j n) 
            (if (eq? #t (vector-ref vec j)) 
                (begin (lp p q j q (eradicate q p vec))) 
                (lp p q j k vec)) 
            #t))))) 

我想使用该函数返回一个向量,该向量可以转换为具有函数sieve-to-list的列表:

(define (sieve-to-list s upperlimit)
  (let aux ((i 2) (acc '()))
    (if (> i upperlimit)
        (reverse acc)
        (if (= (vector-ref s i) 1)
            (aux (add1 i) (cons i acc))
            (aux (add1 i) acc)))))

不幸的是,我不确定第一个函数是否返回一个向量,因为(vector? (prime-sieve 1000))返回#f。当我运行下面的代码并尝试查看前1000个素数的列表时:

(sieve-to-list (prime-sieve 1000) 1000)

我收到错误:

  

vector-ref:合同违规
期望:向量?
给出:#t
参数位置:第1个其他参数......:

如果我将prime-sieve中的#t更改为“给定”后显示的其他内容。

我对矢量知之甚少。如果筛子没有返回矢量,为什么不返回矢量?如何让它返回矢量?如果它确实返回了一个向量,为什么我的转换函数不起作用呢?

0 个答案:

没有答案