Scheme SICP帮助我理解这一点

Scheme SICP帮助我理解这一点,scheme,primes,sicp,factors,primality-test,Scheme,Primes,Sicp,Factors,Primality Test,下面的程序查找给定数字n的最小整数因子(大于1)。它以一种简单的方式实现了这一点,通过测试n是否被从2开始的连续整数整除 (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)

下面的程序查找给定数字n的最小整数因子(大于1)。它以一种简单的方式实现了这一点,通过测试n是否被从2开始的连续整数整除

(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)))

查找除数的结束测试基于这样一个事实,即如果n不是素数,它必须有一个小于或等于n的除数。44这意味着算法只需要测试1到n之间的除数。因此,将n标识为素数所需的步骤数将具有增长顺序(n)。

您的上一段复制时出现了一些错误。这是sqrt(n),而不是n,从阅读代码中可以明显看出

要理解这段代码,您需要慢慢地阅读。这本书的作者以这种冗长的方式编写了他们的代码,这样就可以慢慢地用英语阅读,并在阅读时理解它。据我所知,这是他们的目标

像这样:

(define (smallest-divisor n)
  (find-divisor n 2))
我们将一个数n的最小除数定义为找到一个起始值为2的n的除数的结果。所以我们不认为1是一个数的除数。到目前为止还不错

(define (find-divisor n test-divisor)
找到一个以测试除数的起始值为n的除数是由以下步骤完成的(好吧,我们知道我们从2开始;因为它是一个参数,这段代码准备使用给定给它的任何值…这些值是什么?现在我们知道2是一种可能性;让我们保留这个想法,稍后再检查):

  • 首先将测试除数的平方与n进行比较,如果平方大于n,则返回n作为结果。我们找到了

        ((divides? test-divisor n) test-divisor)
    
        (else (find-divisor n (+ test-divisor 1)))))
    
  • 如果前面的测试不成功,我们接下来将尝试测试测试除数是否除以n。如果是,我们返回测试除数作为结果。我们找到了

        ((divides? test-divisor n) test-divisor)
    
        (else (find-divisor n (+ test-divisor 1)))))
    
  • 如果之前的所有测试都失败了,那么我们就找到了问题的关键:

    • 用未平移的测试除数值查找数字n的除数与用该测试除数值的起始值加1查找数字n的除数相同

    这只是简单的英语意思,“让我们试着用下一个测试数字除以n”

  • (……那么,除了2之外,测试除数可能有哪些值?)


    你现在能完成吗

    您的最后一段被复制,但有一些错误。这是sqrt(n),而不是n,从阅读代码中可以明显看出

    要理解这段代码,您需要慢慢地阅读。这本书的作者以这种冗长的方式编写了他们的代码,这样就可以慢慢地用英语阅读,并在阅读时理解它。据我所知,这是他们的目标

    像这样:

    (define (smallest-divisor n)
      (find-divisor n 2))
    
    我们将一个数n的最小除数定义为找到一个起始值为2的n的除数的结果。所以我们不认为1是一个数的除数。到目前为止还不错

    (define (find-divisor n test-divisor)
    
    找到一个以测试除数的起始值为n的除数是由以下步骤完成的(好吧,我们知道我们从2开始;因为它是一个参数,这段代码准备使用给定给它的任何值…这些值是什么?现在我们知道2是一种可能性;让我们保留这个想法,稍后再检查):

  • 首先将测试除数的平方与n进行比较,如果平方大于n,则返回n作为结果。我们找到了

        ((divides? test-divisor n) test-divisor)
    
        (else (find-divisor n (+ test-divisor 1)))))
    
  • 如果前面的测试不成功,我们接下来将尝试测试测试除数是否除以n。如果是,我们返回测试除数作为结果。我们找到了

        ((divides? test-divisor n) test-divisor)
    
        (else (find-divisor n (+ test-divisor 1)))))
    
  • 如果之前的所有测试都失败了,那么我们就找到了问题的关键:

    • 用未平移的测试除数值查找数字n的除数与用该测试除数值的起始值加1查找数字n的除数相同

    这只是简单的英语意思,“让我们试着用下一个测试数字除以n”

  • (……那么,除了2之外,测试除数可能有哪些值?)


    你现在能完成吗

    你的问题是什么?你的问题是什么?函数(find divisor n test divisor)是尾部递归的。这意味着,该算法是迭代的。这是对递归算法的改进。函数(find divisior n test divisior)是尾部递归的。这意味着,该算法是迭代的。这是对递归算法的改进。