【SICP练习】22 练习1.28
来源:互联网 发布:淘宝收不到卖家消息 编辑:程序博客网 时间:2024/06/09 13:46
练习1.28
这道题主要分为三个部分:
1、非平凡平方根,并添加到expmod函数中
2、类似于fermat-test的过程
3、通过已知的素数和非素数来检验
下面我们首先来写出能够在遇到非平凡平方根的时候报错的函数,在这个函数中:当x不等于1,x不等于(n-1),并且x的平方对n取余等于1,这三个条件都为真时则可以说遇到了“1取模n的非平凡平方根”。下面是该函数:
(define (not-square-root? x n)
(and (not (= x 1))
(not (= x (- n 1)))
(=1 (remainder (square x) n))))
然后我们要将这个函数添加到expmod中,在cond里面添加一项即可:
(define (expmod base exp m)
(cond ((= exp 0) 1)
((not-square-root? base m) 0)
((even? exp)
(remainder (square (expmod base (/ exp 2) m)) m))
(else (remainder (* base (expmod base (-exp 1) m)) m))))
第一步我们已经完成了,下面来看看第二步。在fermat-test中,已经有了一个try-it函数,但这个函数在这道题里不适用,因此我们来自己写一个产生随机数的函数。这个函数用来生成大于0并且小于n的随机数。
(define (zero-to-n-random x)
(let((r (random x)))
(if (not (= r 0))
r
(zero-to-n-randomx))))
random并不会参数负数的随机数,也不能用负数作为参数来产生随机数。下面我们来继续完成miller-rabin-prime函数。
(define (miller-rabin-prime? n)
(let((x (ceiliing (/ n 2))))
(miller-rabin-test n x)))
(define (miller-rabin-test n x)
(cond ((= x 0) #t)
((= (expmod (zero-to-n-random n) (- n 1) n) 1)
(miller-rabin-testn (- x 1)))
(else #f)))
最后还剩下测试的工作了:
(miller-rabin-prime? 1729)
;Value: #f
(miller-rabin-prime? 2821)
;Value: #f
(miller-rabin-prime? 31)
;Value: #t
- 【SICP练习】22 练习1.28
- SICP 练习1.28
- 【SICP练习】2 练习1.6
- 【SICP练习】3 练习1.7
- 【SICP练习】4 练习1.8
- 【SICP练习】5 练习1.9
- 【SICP练习】6 练习1.10
- 【SICP练习】7 练习1.11
- 【SICP练习】8 练习1.12
- 【SICP练习】9 练习1.15
- 【SICP练习】10 练习1.16
- 【SICP练习】11 练习1.17
- 【SICP练习】12 练习1.18
- 【SICP练习】13 练习1.19
- 【SICP练习】14 练习1.20
- 【SICP练习】15 练习1.21
- 【SICP练习】16 练习1.22
- 【SICP练习】17 练习1.23
- Centos MySQL5.6安装方法
- UML类图几种关系的总结
- 【SICP练习】21 练习1.27
- 手把手教你玩转GDB(四)——–函数调用栈(call stack)探密
- [Scoi2010]幸运数字解题报告
- 【SICP练习】22 练习1.28
- C# 流操作
- C语言中 extern "C"使用
- 初探SQLMAP
- C++拾遗--lambda表达式
- 【SICP练习】23 练习1.29
- 升级到VMWARE11后,vmcore/vmm/main/physMem_monitor.c:1123错误解决
- Git使用手册:创建一个Git仓库
- Action接收参数的3种方式(属性,域模型,模型驱动,struts2.1.8)