我是该方案编程语言的新鲜事物,我只是找不到这两种代码之间的区别,尤其是我指出的行。
;program that returns the Nth element in a list where N is an integer argument
(define getElement
(lambda (N L)
(cond
((null? L) '() )
((= N 1) (car L))
(#t(getElement (- N 1) (cdr L)));this line
)
)
)
;takes a list L and a number N and returns the list L but with the first N elements removed
(define remove
(lambda (N L)
(cond
((null? L) '() )
((= N 0) L)
(#t(remove (- N 1) (cdr L)));and this line
)
)
)
为什么这些程序的输出如此不同?除了检查列表是否为空外,以及整数n是否为某个值之外,我看不到这2行对程序输出的影响是什么。
这是我的第一篇文章,因此欢迎任何建议
两个功能都是递归的,并且使用相同的递归策略。但是,当您到达递归的底部时,它们会做非常不同的事情。
每个函数都会减少n,并通过一个元素减少列表,在新上下文中自称。因此,在这两种情况下,列表(至少在函数的参数中表示(都变得越来越短。删除函数返回整个剩余列表。由于已经从删除函数参数中的列表副本中删除了许多元素,因此这具有返回缩短列表的效果。但是,nth-element函数不会返回列表。它返回(CAR L(,或返回L中包含的CONS单元中的元素。也就是说,它仅返回列表的当前元素。这就是为什么他们产生不同的结果。
正如您所说的,
如果整数n是一定值,请执行此操作
的区别在于"做"。
第一个,
((= N 1) (car L))
说"要获取列表的第一个元素,请获取列表的car
"。
第二个,
((= N 0) L)
说"要从列表中删除任何元素,请返回整个列表"。
递归看起来完全相同,但是第一个读取"从列表的cdr
获取元素N - 1
",而第二个读取"从列表的cdr
中删除N - 1
元素"。
(看起来第一个功能已从LISP翻译,其中nil
为" false-y"。更方案y函数将返回#f
。(
您指出的行也相同。绝对没有区别!它会随着索引减少而递归,列表更改为cdr
。
当基本情况击中第一个返回第一个元素时,第二个元素返回列表。
(getElement 1 '(1 2 3)) ; ==> 1, Since it does (car L)
(remove 0 '(1 2 3)) ; ==> (1 2 3), since it does L
现在,如果您的getElement
像list-ref
0
一样工作,应该是基本情况,与remove
相同。另外,当列表为空之前,它在索引为零之前发出错误。这更像是这样:
#!r6rs
(import (rnrs))
(define (my-list-ref lst pos)
(cond ((null? lst) (raise 'list-too-short))
((zero? pos) (car lst))
(else (my-list-ref (cdr lst) (- pos 1)))))
(my-list-ref '() 1)
; ==> uncaught exception: list-too-short