SICP学习笔记 1.2.6 实例:素数检测
2012-06-04 11:08
36 查看
练习1.22
;; runtime函数在stk、racket中都不支持,而GNU的Mit-Scheme十分难用,而且在Fedora16上编译安装后启动就报错, ;; 后来总算是在selinux的提示下让它能够正常启动了 ;; grep scheme /var/log/audit/audit.log | audit2allow -M mypol ;; semodule -i mypol.pp (define (start-prime-test n start-time) (and (prime? n) (report-prime n (- (runtime) start-time)))) (define (prime? n) (= n (smallest-divisor n))) (define (report-prime n elapsed-time) (display n) (display " *** ") (display elapsed-time) (newline)) (define (search-for-primes n) (if (even? n) (search-for-primes-iter (+ n 1) 3 (runtime)) (search-for-primes-iter n 3 (runtime)))) (define (search-for-primes-iter n count start-time) (if (= count 0) ((newline) (display "search over")) (if (start-prime-test n start-time) (search-for-primes-iter (+ n 2) (- count 1) (runtime)) (search-for-primes-iter (+ n 2) count (runtime))))) ;; 数据太小的话根本不能进行比较 (search-for-primes 10000000000) 10000000019 *** .23 10000000033 *** .23 10000000061 *** .24 search over (search-for-primes 100000000000) 100000000003 *** .75 100000000019 *** .73 100000000057 *** .73 search over (search-for-primes 1000000000000) 1000000000039 *** 2.34 1000000000061 *** 2.33 1000000000063 *** 2.33 search over ;; 耗时大概呈√10倍增长
练习1.23
;; 修改如下 (define (next test) (if (= n 2) 3 (+ n 2))) (define (find-divisor n test-divisor) (cond ((> (square test-divisor) n) n) ((divides? test-divisor n) test-divisor) (else (find-divisor n (next test-divisor))))) (search-for-primes 10000000000) 10000000019 *** .13 10000000033 *** .14 10000000061 *** .14 search over (search-for-primes 100000000000) 100000000003 *** .45 100000000019 *** .45 100000000057 *** .44 search over (search-for-primes 1000000000000) 1000000000039 *** 1.41 1000000000061 *** 1.39 1000000000063 *** 1.41 search over ;; 随着数据的增大,耗时大致呈2倍增长
练习1.24
;; 1009 1013 1019 ;; 1000003 1000033 1000037 timed-prime-test 1009) 1009 *** .39 (timed-prime-test 1013) 1013 *** .42 (timed-prime-test 1019) 1019 *** .44 (timed-prime-test 1000003) 1000003 *** .77 (timed-prime-test 1000033) 1000033 *** .76 (timed-prime-test 1000037) 1000037 *** .79 ;; lg n^2 = 2 * lg n,对比以上结果,比较接近,预计测试数据增大后将更加接近
练习1.25
理论上可行,但是直接求base^exp的话可能会因为结果太大而出现溢出
练习1.26
修改后将对于base^2n进行如下方式的计算过程 --> (base*base*base*...)*(base*base*base*...)
而原来的方式将进行如下方式的计算过程 --> (base^n)^2 => (base^(n/2)^2)^2 => ...
因此原有方式为O(log n)而修改后为O(n)
练习1.27
;; 561 1105 1729 2465 2821 6601 (define (expmod base exp m) (cond ((= exp 0) 1) ((even? exp) (remainder (square (expmod base (/ exp 2) m)) m)) (else (remainder (* base (expmod base (- exp 1) m)) m)))) (define (carmichael n) (carmichael-iter n 1)) (define (carmichael-iter n a) (cond ((= a n) true) ((= (expmod a n n) a) (carmichael-iter n (+ a 1))) (else false))) (carmichael 561) ;Value: #t (carmichael 1105) ;Value: #t (carmichael 1729) ;Value: #t (carmichael 2465) ;Value: #t (carmichael 2821) ;Value: #t (carmichael 6601) ;Value: #t
练习1.28
费马小定理: 如果n是素数, 其中1<a<n, 则有 a^n ≡ a (mod n) 变形过程为: 已知 a^n ≡ a (mod n) --> a^n = k*n + a --> a^(n-1) = (k/a)*n + 1 --> a^(n-1) = k'*n + 1 --> a^(n-1) ≡ 1 (mod n) 设n是素数, 其中1<a<n-1, 假设 a^2 ≡ 1 (mod n) --> a^2 - 1 = k*n --> (a+1)*(a-1) = k*n --> (a+1)*(a-1) ≡ 0 (mod n) --> a+1 ≡ 0 (mod n) a-1 ≡ 0 (mod n) --> a = n-1 a = 1 而1<a<n-1,则n不为素数,或不存在1<a<n-1, a^2 ≡ 1 (mod n) ;; 561 1105 1729 2465 2821 6601 (define (miller-rabin n) (miller-rabin-iter n 1)) (define (miller-rabin-iter n a) (cond ((= a n) true) ((= (expmod a (- n 1) n) 1) (miller-rabin-iter n (+ a 1))) (else false))) (define (expmod base exp m) (cond ((= exp 0) 1) ((even? exp) (nontrivial-square-root (expmod base (/ exp 2) m) m)) (else (remainder (* base (expmod base (- exp 1) m)) m)))) (define (nontrivial-square-root a n) (define (try-it value) (if (and (> a 1) (< a (- n 1)) (= value 1)) 0 value)) (try-it (remainder (square a) n))) (miller-rabin 561) ;Value: #f (miller-rabin 1105) ;Value: #f (miller-rabin 1729) ;Value: #f (miller-rabin 2465) ;Value: #f (miller-rabin 2821) ;Value: #f (miller-rabin 6601) ;Value: #f阅读更多
相关文章推荐
- SICP学习笔记:最大公约数和素数检测
- SICP 1.2.6素数检测 fermat检测
- SICP学习笔记 2.2.4 实例:一个图形语言
- 【OpenCV学习笔记】【编程实例】六 (霍夫圆检测续)
- SICP学习笔记 2.1.1 实例: 有理数的算术运算
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检测(2)--主角吃金币
- SICP学习笔记 2.3.2 实例:符号求导
- 【OpenCV学习笔记】【编程实例】五 (霍夫圆检测)
- SICP 1.2.6 素数检测
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》第七步--物理碰撞检测(1)
- Python学习笔记-Turtle库简单实例之日期时间显示
- cocos2d-x 3.0游戏实例学习笔记 《跑酷》 第三步---主角开跑&同一时候带着刚体
- 程序设计的基本元素、过程和计算---SICP学习笔记(1)
- expect学习笔记及实例详解
- iPhone/iPad高级应用与手游开发学习笔记:多点触摸与手势检测(一:UITapGestureRecognizer)
- Jpcap包的学习笔记(五)如何使用JpcapCaptor实例来捕捉网络数据包(上部)
- AJAX 学习笔记(3) Ajax标准交互实例
- PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [4] 首页 APP 接口开发方案 ③ 定时读取缓存方式
- OpenCV学习笔记__角点检测
- C#学习笔记二:用实例深入理解装箱、拆箱