• 【SICP练习】22 练习1.28


    

    练习1.28

    这道题主要分为三个部分:

    1、非平凡平方根,并添加到expmod函数中

    2、类似于fermat-test的过程

    3、通过已知的素数和非素数来检验

    下面我们首先来写出能够在遇到非平凡平方根的时候报错的函数,在这个函数中:当x不等于1x不等于(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

    版权声明:本文为 NoMasp柯于旺 原创文章,如需转载请联系本人。

  • 相关阅读:
    codeforces 673D D. Bear and Two Paths(构造)
    codeforces 673C C. Bear and Colors(暴力)
    codeforces 673B B. Problems for Round(模拟)
    codeforces 673A A. Bear and Game(水题)
    hdu-3555 Bomb(数位dp)
    西交校赛 I. GZP and CS(数位dp)
    西交校赛 F. GZP and Poker
    删除目录下包含“2018” 关键字文件
    CSV转成Excel格式
    解决字符sqlplus 乱码
  • 原文地址:https://www.cnblogs.com/NoMasp/p/4786208.html
Copyright © 2020-2023  润新知