嘿,我一直坚持以下问题,似乎无法提出正确的功能。
写一个递归函数,给定正整数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)))))))
感谢您提前提供帮助......
答案 0 :(得分:1)
先手工做小案。
不试图编码,手动计算答案应该是什么:
在你遇到这些问题之前,你至少应该掌握三个具体的例子:它不仅有助于澄清一些混淆,而且当你得到实际的代码时,它们可以作为完整性测试用例。
您在(分数 - 产品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)
你错了基本情况:它应该说明如果k
是1
,那么返回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))