我对Scheme编程语言很陌生,我只是无法弄清楚这两段代码之间的区别,特别是我指出的那些代码。
;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行对程序输出有什么影响,请执行此操作。
这是我的第一篇文章,欢迎任何建议
答案 0 :(得分:2)
这两个函数都是递归的,并使用相同的递归策略。但是,当你到达递归的底部时,它们会做很多不同的事情。
每个函数将n减少一个,并将列表减少一个元素,在新上下文中调用自身。 因此,列表(至少在函数的参数中表示)在两种情况下都会变得越来越短。 remove函数返回整个剩余列表。由于已经从remove函数的参数中的列表副本中删除了许多元素,因此这具有返回缩短列表的效果。 但是,第n个元素函数不会返回列表;它返回(car l),或者返回l中包含的cons单元格中的元素。也就是说,它只返回列表的当前元素。 这就是他们产生不同结果的原因。
答案 1 :(得分:1)
正如你所说,
如果整数N是某个值,请执行此操作
,区别在于“做这个”。
第一个,
((= N 1) (car L))
说“要获取列表的第一个元素,请选择列表的car
”。
第二个,
((= N 0) L)
说“要从列表中删除任何元素,请返回整个列表”。
递归看起来完全相同,但第一个读取“从列表的N - 1
获取元素cdr
”,而第二个读取“remove {{ 1}}列表中N - 1
的元素“。
(看起来第一个函数已经从Lisp翻译过来,其中cdr
是“false-y”。更多的Scheme-y函数将返回nil
。)
答案 2 :(得分:0)
您指示的行数相同。 完全没有区别!它减少了索引并将列表更改为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