如何使用scheme删除列表中的第三个元素

时间:2013-02-13 02:07:53

标签: scheme racket

这就是我想要的:

(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)。我做错了什么?

3 个答案:

答案 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))