我在Lisp中有这个SICP代码的解决方案:
;; ex 1.11. Iterative implementation
(define (f n)
(define (iter a b c count)
(if (= count 0)
a
(iter b c (+ c (* 2 b) (* 3 a)) (- count 1))))
(iter 0 1 2 n))
我真的不知道Lisp是如何工作的;我在这里理解了一些东西,但我仍然难以将其翻译成Python。例如,我不知道为什么a
写在if
之下。如何将此代码转换为Python或C ++?
(该函数必须是迭代的而不是递归的)
答案 0 :(得分:4)
有两种方法可以考虑翻译。一种是在不尊重Python的习语和惯例的情况下编写直译的文字 - 它看起来像这样:
def f(n):
def iter(a, b, c, count):
if count == 0:
return a
else:
return iter(b, c, 2*b + 3*a + c, count-1)
return iter(0, 1, 2, n)
另一种方法是以Pythonic方式编写代码,使其尊重目标语言的约定并利用其迭代机制:
def f(n):
a, b, c = 0, 1, 2
for count in range(n):
a, b, c = b, c, 2*b + 3*a + c
return a
顺便说一句,第二个版本会更快,并且不会出现堆栈溢出错误(Python 优化递归!)。在递归版本count
从n
转到0
并且循环版本count
从0
转到n
,这是无关紧要的,因为无论如何,除了迭代给定次数之外,count
的值不被用于任何东西。
答案 1 :(得分:2)
我们来看看那段代码:
;; ex 1.11. Iterative implementation
(define (f n)
(define (iter a b c count)
(if (= count 0)
a
(iter b c (+ c (* 2 b) (* 3 a)) (- count 1))))
(iter 0 1 2 n))
首先要注意的是正在定义两个函数。一个是f
,另一个是iter
。 iter
是辅助函数,仅供f
使用(因为它在f
的里面定义了。没有理由你不能实际上,将这两个定义分为:
(define (iter a b c count)
(if (= count 0)
a
(iter b c (+ c (* 2 b) (* 3 a)) (- count 1))))
(define (f n)
(iter 0 1 2 n))
在Lisps中,语法(frob bar1 bar2 ...)
表示您使用参数frob
,bar1
,bar2
调用函数...
。所以f
(define (f n)
(iter 0 1 2 n))
应该比较清楚。您定义的函数f
只接受一个参数n
,然后您使用四个参数[{1}},iter
调用函数0
,1
和2
。那么n
做了什么?
iter
(define (iter a b c count)
(if (= count 0)
a
(iter b c (+ c (* 2 b) (* 3 a)) (- count 1))))
有四个参数。首先,它会检查iter
是否为count
。如果是,则0
返回iter
。否则,a
会以iter
,b
递归调用自己。 c
和(+ c (* 2 b) (* 3 a))
以及递归调用返回的值。基于上面的Lisp语法描述,您应该能够告诉(- count 1)
只是数学表达式 c + 2b + 3a ,而(+ c (* 2 b) (* 3 a))
只是计数-1
我想,关于所有这一切最棘手的部分是知道(- count 1)
有三个参数:第一个是测试表达式;第二个是“当时”部分,也称为结果;第三个是“其他”部分,也称为替代品。与if
仅用于有条件地执行某些语句的其他语言不同,if
在Lisp中返回值,并且该值是结果的值或者替代值,取决于测试的值是真还是假。
通过此描述,您应该能够使用您熟悉的任何编程语言编写对应文件。
当然,一旦你理解了所有这些,你可能会读一些Chris Rathman's translation of SICP code into Python,其中包括练习1.11中代码的翻译:
(if ...)
答案 2 :(得分:1)
这基本上就是在C
中看起来如何int iter (int a, int b, int c, int count)
{
if( count == 0 )
return a;
else
return iter(b, c, c + (2 * b) + (3 * a), count - 1);
}
Scheme中的每个表达式都计算为一个值,因此它是隐式返回。 if
返回分支运行的任何内容,iter返回if返回的内容,依此类推。
不确定这看起来像一个递归序列,它引用前面的3个数字来计算在Scheme中迭代到常量堆栈的下一个数字。请注意,Python不会对尾部调用进行优化,并且C ++和C可能需要特殊的编译器选项和能够编译的编译器。