SICP 習題 1 22 解題總結

2021-06-18 07:48:31 字數 2382 閱讀 3232

sicp 習題 1.22 要求改進題中列舉出來檢查素數的過程,用來求1000, 10000, 100 000,還有1000 000附近的素數,然後比較求這些素數的時間,看是否符合θ(√n)

的複雜度。

要完成這道題首先要將題目中列出的過程照抄到你的scheme環境中。因為書中的**使用了(runtime)過程,我就先在我的環境中測試了(runtime)的結果,很悲劇地發現(runtime)的返回值好幾秒才變乙個數字,根本沒辦法用來紀錄計算過程所需要的時間。於是去查mit-scheme的參考文件,找到過程(real-time-clock) ,發現(real-time-clock)還靠譜一點,返回的是乙個很長的整數,每次手工執行(real-time-clock)都返回乙個不同的數值。

於是使用(real-time-clock)代替(runtime)寫了以下過程:

(define (timed-prime-test n)

(start-prime-test n (real-time-clock)))

(define (start-prime-test n start-time)

(if (prime? n)

(begin

(report-prime n (- (real-time-clock) start-time))

#t)#f))

(define (report-prime number elapsed-time)

(display number)

(display " *** ")

(display elapsed-time)

(newline))

除了使用(real-time-clock)代替(runtime)以外,這裡的過程**和書中的也不太一樣,主要是一些輸出的過程有調整,這樣在後面的使用中不會那麼囉嗦。另外新增了返回值,表示檢查的目標數是否為素數。

有了以上過程就可以去檢查任意乙個數是否為素數,如果是的話會列印檢查所花費的時間,同時返回#t。

接著按題目要求,定義過程去查詢比1000大的三個素數,還有比10000, 100 000,1000 000大的三個素數,看花費多長時間。

我定義的過程如下:

(define (find-prime start end number)

(if (even? start)

(find-prime (+ start 1) end number)

(find-prime-iter start end 0 number)))

(define (find-prime-iter start end cur-number max-number)

(if (and (< start end) (< cur-number max-number))

(if (timed-prime-test start)

(find-prime-iter (+ start 2) end (+ 1 cur-number) max-number)

(find-prime-iter (+ start 2) end cur-number max-number))

cur-number))

過程(find-prime)接受三個引數:查詢的起點,終點,還有需要查詢的素數個數,如果找到的素數超過指定的數量,或者知道終點都沒有找足指定數量的素數,過程都會返回,返回值是找到的素數個數。

後來測試了一下,發現找比1000大的三個素數沒有多大意義,因為計算機太快,總認為在0單位時間內就找到三個素數。

後來就增加了測試數的大小。 增加到10 000 000的時候開始出現有意義的結果,執行結果如下:

1 ]=> (find-prime 10000000 10002000 3)

10000019 *** 5

10000079 *** 5

10000103 *** 5

;value: 3

1 ]=> (find-prime 100000000 100002000 3)

100000007 *** 16

100000037 *** 14

100000039 *** 15

;value: 3

1 ]=> (find-prime 1000000000 1000002000 3)

1000000007 *** 48

1000000009 *** 50

1000000021 *** 46

;value: 3

可以發現查詢100000000附近的素數花費的時間大概是查詢10000000附近的素數時間的3倍。

總結來講,就是目標數大10倍,檢驗它是否為素數的時間就大3倍。

這一點和書中要求我們檢查的「根號10」的結果接近,因為「根號10」的計算結果大概就是3左右。

SICP 習題 1 14 解題總結

sicp 習題 1.14要求計算出過程count change的增長階。count change是書中1.2.2節講解的用於計算零錢找換方案的過程。要解答習題1.14,首先你需要理解count change的工作方式,要理解count change的工作方式,最好是自己去實現一遍count chan...

SICP 習題 1 25 解題總結

sicp 習題 1.25 就是我上面說過的傷自尊的題了。習題1.25說到有個叫allyssa p.hacker的人說expmod過程完全沒有必要搞那麼麻煩,直接使用前面的fast expt過程和remainder過程就好了,她 叫alyssa的應該是女的吧 覺得可以這樣定義expmod define...

SICP 習題 (1 29)解題總結

sicp 習題 1.29 要求辛普森規則求函式f在範圍a 和 b之間的定積分的近似值。在經過前面習題的磨練之後,我對這種充滿數學定義的題目已經麻木了,覺得自己能完成題目就行,有些時候不需要去理會哪些折磨人的數學定義,比如什麼函式的定積分,更不用說什麼辛普森規則。其實sicp在1.3.1這節主要講的是...