用于查找给定数量的因子的方案程序

时间:2015-02-06 11:29:43

标签: scheme

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

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

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

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

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

1 个答案:

答案 0 :(得分:3)

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

请记住,在Scheme中,一切都是表达式并且必须返回一个值,但是有一个你没有考虑的情况:如果(>= f n)会发生什么?这是函数逻辑中的漏洞,这就是我的意思:

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

此外,如果您打算返回所有因子,则必须打印它们或在递归中的每个点处将它们累积在列表中,否则将仅返回最后的结果。最后但并非最不重要的是,该算法简直无法工作。它需要从头开始重写。假设您只想打印结果,此解决方案会考虑我以前的所有建议:

(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中更惯用的解决方案将返回一个包含所有值的列表,而不是沿途打印它们,使用尾递归来获得更好的性能:

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