Dưới đây là nỗ lực của tôi, trong sơ đồ R5RS (từ chối trách nhiệm: Tôi thực sự không phải là một Schemer (chưa!), Vì vậy, xin lỗi (có lẽ) mã khủng khiếp).
(define count 10)
; `factors` is our vector of linked-lists of factors. We're adding to these
; as we go on.
(define factors (make-vector count 'not-found))
(vector-set! factors 0 '())
; `primes-so-far` contains all the prime numbers we've discovered thus far.
; We use this list to speed up the dividing of numbers.
; `primes-so-far-last` is a ref to the last entry in the `primes-so-far`
; list, for O(1) appending to the list.
(define primes-so-far '(dummy))
(define primes-so-far-last primes-so-far)
;; Helpers
(define (factor-ref n)
(vector-ref factors (- n 1)))
(define (factor-cached? n)
(not (eq? (vector-ref factors (- n 1)) 'not-found)))
(define (factor-put n factor)
(let* ((rest (/ n factor))
(factor-cell (cons factor (factor-ref rest))))
(vector-set! factors (- n 1) factor-cell)
factor-cell))
(define (prime-append n)
(let ((new-prime-cell (cons n '())))
(set-cdr! primes-so-far-last new-prime-cell)
(set! primes-so-far-last new-prime-cell)
new-prime-cell))
;; The factor procedure (assumes that `[1..n-1]` have already been factorized).
(define (factor n)
(define (divides? m n)
(= (modulo n m) 0))
; n the number to factor.
; primes the list of primes to try to divide with.
(define (iter n primes)
(cond ((factor-cached? n)
(factor-ref n))
((null? primes)
; no primes left to divide with; n is prime.
(prime-append n)
(factor-put n n)) ; the only prime factor in a prime is itself
((divides? (car primes) n)
(factor-put n (car primes))
(factor-ref n))
(else
(iter n (cdr primes)))))
(iter n (cdr primes-so-far)))
(define (print-loop i)
(if (<= i count)
(begin
(display i)
(display ": ")
(display (factor i))
(newline)
(print-loop (+ i 1)))))
(print-loop 1)
In dưới dạng:
1: ()
2: (2)
3: (3)
4: (2 2)
5: (5)
6: (2 3)
7: (7)
8: (2 2 2)
9: (3 3)
10: (2 5)
(Không chính xác như trong mô tả tác vụ, nhưng tất cả những gì bạn phải làm để có được đầu ra đó là gấp danh sách và hợp nhất các lần lặp lại của cùng một số, trong phần đầu ra của mã. Thuật toán / biểu diễn bên trong vẫn sẽ là giống nhau.)
Ý tưởng là lưu trữ các giá trị được tính toán trước đó, nhưng sử dụng thực tế là các yếu tố n
là yếu tố chính đầu tiên n
và các yếu tố chính của (n / yếu tố đầu tiên). Nhưng cái sau đã được biết đến, vì vậy chúng tôi chỉ sử dụng lại danh sách các yếu tố đã có cho số lượng nhỏ hơn đó. Do đó, đối với mỗi số [1..n]
không phải là số nguyên tố, một ô khuyết duy nhất được lưu trữ.
Đối với mỗi số, một ô khuyết được tạo và lưu trữ. Vì vậy, phương pháp này nên chạy với O(n)
việc sử dụng lưu trữ. Tôi không biết liệu có thể diễn đạt gọn gàng sự phức tạp của thời gian không.