这就是我要的:
(delete-third1 '(3 7 5)) ==> (3 7)
(delete-third1 '(a b c d)) ==> (a b d)
所以我做了类似的事情:
(define (delete-third1 LS ) (list(cdr LS)))
返回
(delete-third1 '(3 7 5))
((7 5))
什么时候应该(3 7)
。我究竟做错了什么?
想想在cdr
做什么。cdr
说“给定一个列表,砍掉第一个值并返回列表的其余部分”。所以它只删除第一个值,然后返回该列表的其余部分(这正是您所看到的)。由于它返回一个列表,因此您也不需要list (cdr LS)
那里。
你想要的是这样的:
(define (delete-n l n)
(if (= n 0)
(cdr l)
(append (list (car l)) (delete-n (cdr l) (- n 1)))))
(define (delete-third l)
(delete-n l 2))
那么这是如何工作的呢?delete-n
将通过保持我们正在处理的元素的运行计数来删除n
列表的第 th 元素。如果我们没有达到n
第 th 个元素,则将该元素添加到列表中。如果是,则跳过该元素并将其余元素添加到我们的列表中。
然后我们简单地定义delete-third
它delete-n
删除第 3 个元素的位置(当我们从 0 开始计数时,它是第 2 个元素)。
这有效:
(define (delete-third! l)
(unless (or (null? l)
(null? (cdr l))
(null? (cddr l)))
(set-cdr! (cdr l) (cdddr l)))
l)
如果您想要一个不修改列表的版本:
(define (delete-third l)
(if (not (or (null? l)
(null? (cdr l))
(null? (cddr l))))
(cons (car l) (cons (cadr l) (cdddr l)))
l))
如果您想对任何第 n 个元素执行此操作:
(define (list-take list k)
(assert (not (negative? k)))
(let taking ((l list) (n k) (r '()))
(if (or (zero? n) (null? l))
(reverse r)
(taking (cdr l) (- n 1) (cons (car l) r)))))
(define (delete-nth l n)
(assert (positive? n))
(append (list-take l (- n 1))
(if (> n (length l))
'()
(list-tail l n))))
(define (nth-deleter n)
(lambda (l) (delete-nth l n)))
(define delete-3rd (nth-deleter 3))
最简单的方法是:将第一个元素、第二个元素和列表的其余部分从第四个位置开始。因为这看起来像作业,所以我只会给你大致的想法,所以你可以填空:
(define (delete-third1 lst)
(cons <???> ; first element of the list
(cons <???> ; second element of the list
<???>))) ; rest of the list starting from the fourth element
以上假设列表至少包含三个元素。如果情况并非总是如此,请首先验证列表的大小并针对该情况返回适当的值。
更多提示:在 Racket 中有一个用于访问列表第一个元素的直接过程。另一个用于访问第二个元素。最后,您始终可以使用cdr
s 序列来到达 ... 列表的其余部分(但即使这样也可以写得更紧凑)
从实际的角度来看,如果这不是功课,您可以根据其他现有程序轻松实现此功能,甚至使其足够通用以删除任何给定位置的元素。例如,要删除第三个元素(再次假设列表中有足够的元素):
(append (take lst 2) (drop lst 3))
或者作为从给定的基于 0 的索引中删除元素的一般过程:
(define (remove-ref lst idx)
(append (take lst idx) (drop lst (add1 idx))))
以下是我们删除第三个元素的方法:
(remove-ref '(3 7 5) 2)
=> '(3 7)