Scheme递归函数

时间:2012-09-11 02:51:55

标签: recursion scheme racket r5rs

嘿,我一直坚持以下问题,似乎无法提出正确的功能。

写一个递归函数,给定正整数k,计算乘积k: (1-1 / 2)(1-1 / 3)(1-1 / k)......当k减1时。

我似乎无法想出正确的功能,程序通常运行直到它没有剩余的内存。这是我的方法:

(define (fraction-product k)
  (if (= k 0)
       0
       (* (- 1 (/ 1 (fraction-product (- k 1)))))))

感谢您提前提供帮助......

3 个答案:

答案 0 :(得分:1)

先手工做小案。

不试图编码,手动计算答案应该是什么:

  • (分数产品1)
  • (分数产品2)
  • (分数产品3)

在你遇到这些问题之前,你至少应该掌握三个具体的例子:它不仅有助于澄清一些混淆,而且当你得到实际的代码时,它们可以作为完整性测试用例。

您在(分数 - 产品1)(分数 - 产品2)之间计算的答案之间是否存在关系? (馏分 - 产品2)(馏分 - 产品3)之间怎么样?

我们是否必须担心(分数产品0)?检查你的问题陈述。

当你看到这样的问题时,不要直接编码。先用手做一些小例子:计算应该的答案。它将有助于启动您对程序实际计算内容的直觉,以及如何以机械方式进行计算。

如果你有时间,请参阅像How to Design Programs这样的书,它描述了设计这些功能的系统方法。

答案 1 :(得分:0)

该产品的论点是什么?只有一个! 因此(* n) == (* n 1) == n,产品无用。 这应该立即告诉您,您的算法没有达到您想要的效果。

找到这样的错误的一个好策略是写出单独行的所有函数参数......

此外,当k == 0时,(fraction-product 0)返回0。 然后(fraction-product 1)将计算(/ 1 (fraction-product 0)) == (/ 1 0),这可能不是您想再做的......

实际上,似乎你想要计算与分数的乘积完全不同的东西......而不是递归分数(我忘记了这些东西的名称)。

无论如何,做(1 - 1/2) * (1 - 1/3) * ... * (1 - 1/k)你可以做点什么

(define (f-p k)
  (define (aux n) (- 1 (/ 1 n)))
  (let loop ((i 2))
    (if (> i k)
      1 ;; base case: multiply by 1, i.e. "do nothing"
      (* (aux i) (loop (+ i 1))))))

这可以优化为使用常量堆栈空间,但它不是重点,是吗?

答案 2 :(得分:0)

你错了基本情况:它应该说明如果k1,那么返回1 - 当你递归相乘时你必须确保递归停止达到1时,如果乘以0,结果将始终为0

递归调用也是错误的,请注意,您必须将(- 1 (/ 1 k))倍乘以递归的结果。尝试这样的事情:

(define (fraction-product k)
  (if (<= k 1)
      1
      (* (- 1 (/ 1 k))
         (fraction-product (- k 1)))))

正如在@ Axioplase的回答中所建议的那样,可以通过使用尾递归来使用常量堆栈空间来编写相同的过程 - 递归调用是过程在返回之前执行的最后一个事务,因此处于尾部位置:

(define (fraction-product k)
  (let loop ((acc 1)
             (k k))
    (if (<= k 1)
        acc
        (loop (* acc (- 1 (/ 1 k))) (- k 1)))))

只是为了好玩,很容易意识到同样的程序可以写成这样简单:

(define (fraction-product k)
  (/ 1 k))