我试图理解在这个递归示例中如何使用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)
如何将每次迭代添加到函数中。
答案 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)
add1
将1
添加到其参数中并返回该总和。因此,如果列表其余部分的长度为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