【发布时间】:2013-04-14 11:24:24
【问题描述】:
我是新来的计划。我正在尝试以新列表不应包含第一个和最后一个元素的方式截断列表。
提前致谢。
【问题讨论】:
我是新来的计划。我正在尝试以新列表不应包含第一个和最后一个元素的方式截断列表。
提前致谢。
【问题讨论】:
有很多方法可以做到这一点,一种可能是使用drop-right 删除最后一个元素并使用rest(或cdr)删除第一个元素:
(define lst '(1 2 3 4 5))
(rest (drop-right lst 1))
=> '(2 3 4)
如果drop-right 在您的解释器中不可用,则只需实现一个过程,该过程返回一个新列表,其中包含输入列表中的所有元素,最后一个除外。您甚至可以在一个过程中结合删除这两个元素。下面是解决方案的大致思路,假设列表至少有两个元素(否则会发生错误)- 填空:
(define (truncate-first-last lst)
(define (drop-last lst) ; helper procedure for removing last element
(if <???> ; if the rest of the list is empty
<???> ; then return the empty list
(cons <???> ; else `cons` the first element
(drop-last <???>)))) ; and advance the recursion
(drop-last <???>)) ; call helper, remove first element from list
别忘了测试它:
(truncate-first-last '(1 2 3 4 5))
=> '(2 3 4)
【讨论】:
cdr 代替rest(如上所述)。至于drop-right,上一段提示,实现一个drop-last的过程,很简单:在创建新列表的同时遍历输入列表(这种操作使用模板,教科书中有),唯一不同的是,递归在列表的cdr 为null? 时结束,而不是在列表为null? 时结束,通常情况下
cond 形式中,最后一个子句是else(Scheme 方式),而不是#t(Common Lisp 方式)。而append 是不必要的,trunc-fl 的主体只是(drop-last (cdr lst))
你可以这样做:
(define (compose f1 . fn)
(cond ((null? fn) f1)
(else (let ((fr (apply compose fn)))
(lambda (x) (f1 (fr x)))))))
(define truncate-first-last (compose reverse cdr reverse cdr))
> (truncate-first-last '(1 2 3 4))
(2 3)
【讨论】: