以下程序找到给定数n的最小整数除数(大于1)。它通过以2开始的连续整数测试n的可除性来直接实现这一点。
(define (smallest-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(define (divides? a b)
(= (remainder b a) 0))
我们可以测试一个数是否是素数如下:当且仅当n是它自己的最小除数时,n才是素数。
(define (prime? n)
(= n (smallest-divisor n)))
find-divisor的结束测试基于以下事实:如果n不是素数,则它必须具有小于或等于n.44的除数。这意味着该算法仅需要测试1和n之间的除数。因此,将n识别为素数所需的步骤数将具有增长顺序(n)。
答案 0 :(得分:2)
您的上一段被复制时出现了一些错误。它是 sqrt(n),而不是 n ,这在阅读代码时很明显。
要理解此代码,您需要阅读它,慢慢地。本书的作者专门以这种冗长的方式编写了他们的代码,以便可以用英语慢慢阅读,并且在阅读时理解。据我所知,这是他们的目标。
像这样:
(define (smallest-divisor n)
(find-divisor n 2))
我们定义一个数字 n 的最小除数,它是找到 n 除数的结果,其起始值为 2 。所以我们不会将 1 视为数字的除数。到目前为止一切都很好。
(define (find-divisor n test-divisor)
使用起始值 test divisor 查找数字 n 的除数是由(我们知道我们从 2开始 ;因为它是一个参数,这个代码准备使用赋予它的任何值...这些值是什么?现在我们知道 2 是一种可能性;让我们坚持这个想法并重新稍后检查一下):
(cond ((> (square test-divisor) n) n)
首先将 test divisor 的平方与 n 进行比较,如果square大于 n ,则返回<结果是em> n 。我们找到了它!
((divides? test-divisor n) test-divisor)
如果之前的测试不成功,我们接下来会尝试测试测试除数是否划分 n 。如果是,我们返回 test divisor 作为结果。我们找到了它!
(else (find-divisor n (+ test-divisor 1)))))
如果之前的所有测试都失败了,我们就会遇到问题:
这只是用简单的英语表示,“让我们尝试将 n 与下一个测试号码分开”。
(....那么, test divisor 可能有哪些值,除了 2 ?)
(define (divides? a b)
(= (remainder b a) 0))
你能完成它吗?