这就是我想要的:
(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)
。我做错了什么?
答案 0 :(得分:3)
考虑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
元素,方法是保持我们所处理元素的运行计数。如果我们没有达到n
元素,那么将该元素添加到列表中。如果我们是,那么跳过该元素并将其余元素添加到我们的列表中。
然后我们简单地将delete-third
定义为delete-n
,删除第3个元素(当我们从0开始计数时是元素2)。
答案 1 :(得分:0)
最简单的方法是:从第四个位置开始,构成第一个元素,第二个元素和列表的其余部分。因为这看起来像家庭作业我只会给你一般的想法,所以你可以填写空白:
(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
来达到...列表的其余部分(但即使这样也可以更紧凑地编写)
从实际角度来看,如果这不是作业,您可以根据其他现有程序轻松实现此功能,甚至可以使其足够通用以删除任何给定位置的元素。例如,删除第三个元素(并再次假设列表中有足够的元素):
(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)
答案 2 :(得分:0)
这有效:
(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))