求给定数的因数的方案程序

Scheme program to find factors of a given number

我最近开始学习方案并测试我的技能我决定设计一个程序来打印给定数字的所有因素。

但是,程序没有返回任何输出。不知道是什么原因,我觉得我已经把除法的条件检查得很好了。

这是我的代码。问题出在哪里?我无法确定它。

(define 
    (factors n f)
    (if (= 0 (remainder n f) )
        f )
    (if (< f n) 
        (factors n (+ f 1))))

过程的名称是因素。它需要两个输入数字:nfN 是必须找到因子的数字。 F 是打印 n 的因数的数字。

您的代码有几个错误。对于初学者,您永远不应该使用单臂 if 表达式(即没有 "else" 部分的 if);如果发生这种情况,一些解释器会更进一步并引发编译错误。此外,您应该使用 cond 而不是嵌套 if

请记住,在 Scheme 中,所有内容都是 表达式 并且必须 return 一个值,但有一种情况您没有考虑:如果 (>= f n)?这是函数逻辑上的一个漏洞,这就是我的意思:

(define (factors n f)
  (if (= 0 (remainder n f))
      f
      (if (< f n) 
          (factors n (+ f 1))
          ; else?
          )))

此外,如果您打算 return 所有因子,您必须在递归的每个点打印它们或将它们累积在列表中,否则只有最后一个结果会得到 returned .最后但同样重要的是,该算法根本行不通。它需要从头开始重写。假设您只想 打印 结果,此解决方案考虑了我之前的所有建议:

(define (factors n f)
  (cond ((> f n) 'done)
        ((= 0 (remainder n f))
         (display f)
         (newline)
         (factors n (+ f 1)))
        (else
         (factors n (+ f 1)))))

(factors 23174 1)
=> 1
   2
   11587
   23174
   'done

Scheme 中更惯用的解决方案是 return 包含所有值的列表,而不是沿途打印它们,使用尾递归以获得更好的性能:

(define (factors n f)
  (let loop ((f f) (acc '()))    
    (cond ((> f n) (reverse acc))
          ((zero? (remainder n f))
           (loop (add1 f) (cons f acc)))
          (else (loop (add1 f) acc)))))

(factors 23174 1)
=> '(1 2 11587 23174)