add1如何在这个Racket程序中使用?

时间:2014-06-16 08:01:31

标签: recursion scheme lisp racket

我试图理解在这个递归示例中如何使用add1:

(define (my-length a-list)
  (if (empty? a-list)
      0
      (add1(my-length (rest a-list)))))

如果给定(my-list '(1 2 3 4)),程序将返回数字4。

据我所知,在函数my-lenght的每次迭代之后,代码将拆分列表,直到列表为空。我不明白的是(add1)如何将每次迭代添加到函数中。

4 个答案:

答案 0 :(得分:1)

如果您的问题是递归,我建议您trace重复拨打my-length。 例如,在DrRacket中,在定义窗口中编写以下内容:

#lang racket

(require racket/trace)

(define (my-length a-list)
  (if (empty? a-list)
      0
      (add1(my-length (rest a-list)))))

(trace my-length)
(my-length '(a b c d))

点击Run并观察:

>(my-length '(a b c d))
> (my-length '(b c d))
> >(my-length '(c d))
> > (my-length '(d))
> > >(my-length '())
< < <0
< < 1
< <2
< 3
<4
4

您可以看到(my-length '(a b c d))来电(my-length '(b c d))(因为那是(rest '(a b c d))是什么),它会调用(my-length '(c d)),依此类推。调用(my-length '())时,它返回0(if的第一个分支)。此返回值被赋予(返回)前一个调用,(my-length '(d))add1到它的返回值,因此返回1.后一个返回值返回到(my-length '(c d)),返回2,依此类推,直到最后返回4的(my-length '(a b c d))

这里的关键点是add1适用于递归调用的返回值,因此必须等待此调用返回才能使用此返回值执行某些操作。换句话说,与处理列表的方式相比,add1 s的应用顺序相反。

有关详细信息和示例,请参阅racket/trace

答案 1 :(得分:1)

为了另一种解释:

这是我们开始的地方

(my-length '(a b c d))

通过在函数中填入参数,变为

(if (empty? '(a b c d))
  0
  (add1 (my-length (rest '(a b c d)))))

显然,'(a b c d)不是空的。那么&#34;否则&#34;评估if的情况:

(add1 (my-length (rest '(a b c d))))
(add1 (my-length '(b c d)))

现在,(my-length '(b c d))是什么意思?好吧,如果我们将函数体粘贴到最后一行,我们得到:

(add1 (if (empty? '(b c d))
        0
        (add1 (my-length (rest '(b c d))))))

...继续

(add1 (add1 (my-length (rest '(b c d)))))
(add1 (add1 (my-length '(c d))))

这一直持续到我们得到一个空列表:

(add1 (add1 (add1 (add1 (if (empty? '())
                              0
                              (add1 (my-length (rest '()))))))))

'()为空,因此if语句返回0:

(add1 (add1 (add1 (add1 0))))
(add1 (add1 (add1 1)))
(add1 (add1 2))
(add1 3)
4

这就像我们进一步深入了解这个功能一样,因为对于我们采取的每一步,我们需要再做一次来实际评估我们所拥有的功能。


这与(add1 '(a b c d))有什么不同?您可以看到评估的结果是add1从未实际应用于a,b,c或d。我们甚至没有检查过列表中的内容。您可以拥有四个列表的列表,每个列表都包含列表列表,并且会对所有列表进行评估。

具体来说,(add1 '(a b c d))说“&#34;什么是1加草莓?&#34;”,而你的功能更像是:

&#34;此列表中有多少内容?&#34;

&#34;好吧,如果你在顶部看不到任何东西((first my-list)),那么肯定没有。&#34;

&#34;好吧,好吧......我看到&#34; a&#34;在顶部!&#34;

&#34;尼斯!拿出来。这个列表中至少有1个。&#34;

&#34;好的,但剩下多少人了?&#34;

&#34;我们再次尝试同样的事情怎么样?只需从列表顶部取出物品,直到列表为空。然后,我们将它重新组合在一起,并在我们离开时计算。&#34;

&#34;好的,我把它们全部拿走了。我现在要把它们放回去:d,那是1; c,那是2; b,那是3;和a,这使得4!&#34;

&#34;你去了,列表中有4个!&#34;

答案 2 :(得分:0)

add11添加到其参数中并返回该总和。因此,如果列表其余部分的长度为3,则(add1 (my-length (rest a-list)))会将1添加到3并返回4

在空列表的基本情况下,my-length会返回0

(my-length '(4))在递归中调用(my-length '()),返回0,然后在此调用add1返回1

(my-length '(3 4))在递归中调用(my-length '(4))。如上所述,这会返回1,然后在此处调用add1,返回2

等等。

答案 3 :(得分:0)

评估如下:

   (my-list '(1 2 3 4))
-> (add1 (my-list '(2 3 4)))
-> (add1 (add1 (my-list '(3 4))))
-> (add1 (add1 (add1 (my-list '(4)))))
-> (add1 (add1 (add1 (add1 (my-list '())))))
-> (add1 (add1 (add1 (add1 0))))
-> (add1 (add1 (add1 1)))
-> (add1 (add1 2))
-> (add1 3)
-> 4