這道題的題目背景:用尋找最小divisor判斷素性的方法O(n^(1/2))編寫一個能給出給定範圍素數的程序,並能夠計算程序進行的時間
首先我們創建能夠判斷素數的函數
然後我們用給定範圍內的奇數去判斷
(define (test n)
(define starttime (runtime))
(define (smallest-divisor n)
(define (reminder x y) (if (< x y) x (reminder (- x y) y)))
(define (is-divisor? a)
(cond ((= (reminder n a) 0) a)
((> (* a a) n) n)
(else (is-divisor? (+ a 1)))
)
)
(is-divisor? 2)
)
(define (is-prime? n) (= (smallest-divisor n) n))
(define flag (is-prime? n))
(cond (flag (display "\n") (display n)))
flag
(define endtime (runtime))
(- endtime starttime)
)
(define (prime-create minum maxnum)
(define starttime (runtime))
(define (reminder x y) (if (< x y) x (reminder (- x y) y)))
(define (is-even? n) (= (reminder n 2 ) 0) )
(cond ((is-even? minum) (prime-create (+ minum 1) maxnum))
(else
(cond ((< minum maxnum ) (test minum) (prime-create (+ minum 2) maxnum))
((= minum maxnum ) (test minum))
)
)
)
(define endtime (runtime))
(- endtime starttime)
)
這個結果好像和我們的設想不太一樣,那麼我們來分析一下過程 test 997 test 10007 997處理a 2- 33 10007 處理a 2-100 大約3倍多一點這時我們如果假設每步求餘都爲1那麼結果就是符合O的但是,我們這裏的reminder是由減法迭代創建的,也就是reminder這個的時間也是會根據參數的改變而改變,由於參數相差較大,所以reminder在這裏的差異也較大,所以結果不符合O
ex1-18要求在17的前提下修改test將檢測的divisor爲>2的偶數除去
(define (test n)
(define starttime (runtime))
(define (next-divisor n) (cond ((= n 2) 3) (else (+ n 2))))
(define (smallest-divisor n)
(define (reminder x y) (if (< x y) x (reminder (- x y) y)))
(define (is-divisor? a)
(cond ((= (reminder n a) 0) a)
((> (* a a) n) n)
(else (is-divisor? (next-divisor a)))
)
)
(is-divisor? 2)
)
(define (is-prime? n) (= (smallest-divisor n) n))
(define flag (is-prime? n))
(cond (flag (display "\n") (display n)))
flag
(define endtime (runtime))
(- endtime starttime)
)
(define (prime-create minum maxnum)
(define starttime (runtime))
(define (reminder x y) (if (< x y) x (reminder (- x y) y)))
(define (is-even? n) (= (reminder n 2 ) 0) )
(cond ((is-even? minum) (prime-create (+ minum 1) maxnum))
(else
(cond ((< minum maxnum ) (test minum) (prime-create (+ minum 2) maxnum))
((= minum maxnum ) (test minum))
)
)
)
(define endtime (runtime))
(- endtime starttime)
)
基本同ex1-17的結果的一半,符合題意的2倍猜測
解釋,由於它是將偶數項除去(2不算)因此同相鄰奇數項reminder的時間基本一致所以符合2倍關係
ex1-19
要求修改1-17中的test 利用費馬測試來加快test觀察結果是否爲O(logn)並若不是作出解釋
先給代碼
(define (is-prime? n times)
(define starttime (runtime))
(define (fermat n)
(define a (+ 2 (random (- n 2) ) ) )
(define (expmod base Exp div)
(define (reminder x y) (if (< x y) x (reminder (- x y) y)))
(define (square x) (* x x) )
(define (is-even? x) (= (reminder x 2) 0))
(cond ((= Exp 0) 1)
((is-even? Exp) (reminder (square (expmod base (/ Exp 2) div) ) div ) )
(else (reminder (* base (expmod base (- Exp 1) div) ) div ) ) )
)
(= (expmod a n n) a)
)
(cond ((= times 0) #t)
((fermat n) (is-prime? n (- times 1)))
(else #f))
(- (runtime) starttime)
)
(define (test n) (is-prime? n 1))
同1-17分析,依然存在reminder的時間差異,所以基本是O(n)
以上僅個人分析,如有錯誤,請糾正,感謝~~~