Recursion 方案递归函数

Recursion 方案递归函数,recursion,scheme,racket,r5rs,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))))))) 感谢您提前提供的帮助……产品的参数是什么?只有

嘿,我一直被困在下面的问题,似乎不能想出正确的功能

编写一个递归函数,给定正整数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)))))))

感谢您提前提供的帮助……

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

找到这些错误的一个好策略是将函数的所有参数写在单独的行中

另外,当
k==0
时,
(分数乘积0)
返回0。 然后
(分数乘积1)
将计算
(/1(分数乘积0))==(/10)
,这可能不是您希望再次执行的操作

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

无论如何,要做的是
(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))))))

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

基本情况是错误的:它应该声明如果
k
1
,然后返回
1
-当递归乘法时,必须确保递归在达到数字
1
时停止,如果乘以
0
,结果将始终为
0

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

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

先用手做小箱子

无需编写代码,即可手动计算答案:

  • (分数积1)
  • (分数乘积2)
  • (分数积3)
在处理这些类型的问题之前,您至少应该有三个具体的例子在手:这不仅有助于澄清一些混淆,而且当您开始实际的代码时,它们可以作为健全性测试用例

你手工计算的答案(分数积1)和(分数积2)之间有关系吗?(分数乘积2)和(分数乘积3)之间的关系如何

我们需要担心(分数积0)吗?检查你的问题陈述

当你看到这样的问题时,不要直接去编写代码。先手工做一些小例子:计算出答案应该是什么。这将有助于激发你的直觉,让你了解程序真正想要计算的是什么,以及如何机械地进行计算


如果您有时间,请参阅一本书,其中介绍了设计这类函数的系统方法。

无需将尾部递归函数转换为迭代函数:Lisp解释器会自动执行此操作。@Eyal但无论如何,您必须以使用尾部调用的方式编写递归,上述程序的第一个版本不会自动转换为第二个版本。第二个不是迭代函数,是使用命名let编写的尾部递归。
(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))