Điều này thật nhàm chán, tôi biết, nhưng tôi cần một chút trợ giúp để hiểu được việc thực hiện Sàng Eratosthenes. Đó là giải pháp cho this Programming Praxis problem.Giúp hiểu Sàng thực hiện Eratosthenes
(define (primes n)
(let* ((max-index (quotient (- n 3) 2))
(v (make-vector (+ 1 max-index) #t)))
(let loop ((i 0) (ps '(2)))
(let ((p (+ i i 3)) (startj (+ (* 2 i i) (* 6 i) 3)))
(cond ((>= (* p p) n)
(let loop ((j i) (ps ps))
(cond ((> j max-index) (reverse ps))
((vector-ref v j)
(loop (+ j 1) (cons (+ j j 3) ps)))
(else (loop (+ j 1) ps)))))
((vector-ref v i)
(let loop ((j startj))
(if (<= j max-index)
(begin (vector-set! v j #f)
(loop (+ j p)))))
(loop (+ 1 i) (cons p ps)))
(else (loop (+ 1 i) ps)))))))
Phần tôi đang gặp sự cố là startj
. Bây giờ, tôi có thể thấy rằng p
sẽ chuyển động qua các số lẻ bắt đầu từ 3, được định nghĩa là (+ i i 3)
. Nhưng tôi không hiểu mối quan hệ giữa p
và startj
, là (+ (* 2 i i) (* 6 i) 3)
.
Sửa: Tôi hiểu rằng ý tưởng là để bỏ qua số rây trước đó. Định nghĩa câu đố cho biết rằng khi chọn lọc số x
, việc chọn lọc sẽ bắt đầu tại hình vuông x
. Vì vậy, khi chọn 3, bắt đầu bằng cách loại bỏ 9, v.v.
Tuy nhiên, điều tôi không hiểu là cách tác giả đưa ra biểu thức đó cho startj
(đại số nói).
Từ các ý kiến câu đố:
Nói chung, khi chọn lọc bởi n, chọn lọc bắt đầu từ n-squared bởi vì tất cả các bội trước của n đã được sieved.
Phần còn lại của biểu thức phải làm với tham chiếu chéo giữa các số và chỉ mục sàng. Có 2 trong biểu thức vì chúng tôi đã loại bỏ tất cả các số chẵn trước khi chúng tôi bắt đầu. Có 3 trong biểu thức vì các vectơ Scheme không dựa trên 0 và các số 0, 1 và 2 không phải là một phần của rây. Tôi nghĩ rằng 6 thực sự là một sự kết hợp của 2 và 3, nhưng nó đã được một thời gian kể từ khi tôi nhìn vào mã, vì vậy tôi sẽ để nó cho bạn để tìm ra.
Nếu bất cứ ai có thể giúp tôi với điều này, rằng sẽ thật tuyệt. Cảm ơn!
Vâng, bày tỏ đại số chúng ta có 'p = 2i + 3' và 'startj = 2i^2 + 6i + 3', rõ ràng ... rõ ràng ... hm. Đó không phải là cách thực hiện rõ ràng nhất của Sàng mà tôi từng đọc. –
Thật vậy :) Một vài bình luận sẽ được tốt đẹp. – harto
'startj = (i + 1) * p + i' Nó chỉ là bỏ qua một số con số mà có thể đã được sàng lọc bởi các bước trước đó, tôi nghĩ vậy. – ephemient