练习1.23-练习1.30

版权声明:本文为博主原创文章,转载请注明出处,谢谢!

版权声明:本文为博主原创文章,转载请注明出处:http://blog.jerkybible.com/2014/01/20/2014-01-20-练习1.23-练习1.30/

访问原文「练习1.23-练习1.30

1.练习1.23
改后的代码如下:

1
2
3
4
5
6
7
8
9
(define (find-divisor-better n a)
(cond ((> (square a) n) n)
((divides?-better n a) a)
(else (find-divisor-better n (next-2 a)))))
(define (next-2 n)
(if (= 2 n)
(+ 1 n)
(+ 2 n)))
1
2
3
4
5
6
7
(define (find-min-prime-since-better n start-time number)
(cond ((= number 0) (display-info start-time (real-time-clock)))
((prime? n) (begin
(format #t "~S~%" n)
(find-min-prime-since-better (+ n (next-plus n)) start-time (- number 1))))
(else (find-min-prime-since-better (+ n (next-plus n)) start-time number)))
#f)
1
2
3
4
(define (next-plus n)
(if (even? n)
1
2))

电脑跑这些代码的时候,没有固定的运行时间,一直在变。不过结果是改后的基本是没改前的0.5,也可能0.6左右。
2.练习1.24
代码就不贴出来了,只是将上一题中的判断是否为素数的方法改为费马方法。
在检测接近1000000的素数和接近1000的素数时,接近1000000的素数在时间上应该为(log1000000)=6应该大于接近1000的3的素数检查,比值为2:1,实验中计算从1000和1000000开始的1000个素数,1000开始的时间为695,而从1000000开始的时间为1470,比值接近于1:2, 与假设基本相同。
但是在帖子,那我猜,可能是64位和32位的不同了。
3.练习1.25
先求次方的结果会导致一个很大的数求余数,这样的时间消耗会很大。
4.练习1.26
不使用square的结果是每次减半的expmod操作没有了简版的效果,所以时间复杂度会变回O(n) 。
5.练习1.27

1
2
3
4
5
6
7
8
9
10
(define (try-it a n)
(= (expmod a n n) a))
(define (carmichael-test n number)
(cond ((= number 0) true)
((try-it number n) (carmichael-test n (- number 1)))
(else false)))
(define (car-prime? n)
(carmichael-text n (- n 1)))

6.练习1.28

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(define (new-expmod base exp m)
(define tmpbase 100)
(cond ((= exp 0) 1)
((even? exp) (begin
(set! tmpbase (new-expmod base (/ exp 2) m))
(if (and (not (= tmpbase (- m 1)))
(not (= tmpbase 1))
(= (remainder (square tmpbase)
m) 1))
0
(remainder (square tmpbase)
m))))
(else (remainder (* base (new-expmod base (- exp 1) m))
m))))
(define (new-try-it n a)
(new-expmod a (- n 1) n))
(define (new-fermat-test n start)
(cond ((= start 1) true)
((= (new-try-it n start) 0) false)
(else (new-fermat-test n (- start 1)))))
(define (really-prime? n)
(new-fermat-test n (if (even? n)
(/ n 2)
(/ (- n 1) 2))))

没有进行优化,但本身也有可能会有更好的方法吧

Jerky Lu wechat
欢迎加入微信公众号