【SICP练习】22 练习1.28
練習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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Tomcat中配配置数据源汇总
- 下一篇: Linux学习十七、正规表达式练习题