lisp基本递归函数。帮我追踪一下

时间:2018-10-27 23:25:19

标签: common-lisp

Lisp sigma函数递归-帮助我跟踪它。从逻辑上讲,我只需要了解此示例,即可完成我的任务。我不确定第四行和第五行发生了什么,x被设置为什么。如果我的输入为(sigma f 1 2),而我的输出为20,则另一个示例为(sigma f 1 5)。如果可以帮助我进行跟踪。我将在下面发布sigma定义。谢谢您的帮助。

(defun sigma (f m n)
  (if (> m n)
      0
      (let ((x (sigma f (+ m 1) n)))
        (+ (funcall f m)
           x))))

2 个答案:

答案 0 :(得分:5)

您还可以跟踪功能。由于您需要辅助功能,因此我们定义myfun,它将其参数乘以2。

CL-USER> (defun myfun (x) (* x 2))
MYFUN

TRACE两种功能:

CL-USER> (trace sigma myfun)

然后,您应该具有以下内容:

CL-USER> (sigma 'myfun 0 5)
  0: (SIGMA MYFUN 0 5)
    1: (SIGMA MYFUN 1 5)
      2: (SIGMA MYFUN 2 5)
        3: (SIGMA MYFUN 3 5)
          4: (SIGMA MYFUN 4 5)
            5: (SIGMA MYFUN 5 5)
              6: (SIGMA MYFUN 6 5)
              6: SIGMA returned 0
              6: (MYFUN 5)
              6: MYFUN returned 10
            5: SIGMA returned 10
            5: (MYFUN 4)
            5: MYFUN returned 8
          4: SIGMA returned 18
          4: (MYFUN 3)
          4: MYFUN returned 6
        3: SIGMA returned 24
        3: (MYFUN 2)
        3: MYFUN returned 4
      2: SIGMA returned 28
      2: (MYFUN 1)
      2: MYFUN returned 2
    1: SIGMA returned 30
    1: (MYFUN 0)
    1: MYFUN returned 0
  0: SIGMA returned 30
30

答案 1 :(得分:3)

可能有助于理解的第一件事是使用更具描述性的名称:

(defun sigma (some-function current-index end-index) ...)

此功能是一种非常典型的递归模式。首先,有一个基本案例

(if (> m n) 0 ...)

一旦我们到达循环的结尾,就完成了。对于任何f(sigma f 2 1)都是“循环结束时”,并且始终会产生0。

否则,我们不会结束循环,因此存在一个片段“使用下一个索引再次调用此函数”:

(sigma f (+ m 1) n)

“为该索引产生一些结果”的片段:

(funcall f m)

,然后结合两者:

(let ((x (recursive-sigma-call)))
 (+ (value-at-this-index) x))

您可以尝试遍历

(sigma (lambda (x) (* x 2)) 1 2)

手动展开每个表格以查看其工作原理。