从列表中删除第二个出现的给定项目-Racket



我需要编写一个名为remove-2nd的函数,该函数从项列表中删除给定项的第二个顶级项。这就是我现在拥有的:

(define (remove-2nd item list)
(cond
((null? list) '())
((equal? item (car list))
(cdr list))
(else
(cons (car list) (remove-2nd item (cdr list))) 
)))

现在,它只删除第一个引用。(remove-2nd'c'(a b c d c x c((返回(a b d c x c(何时我应该得到(a b c d x c(。

对于空列表和单元素列表,我们只返回列表。否则,我们将查看列表中的第一个项目是否与要删除的项目相同。如果它是我们试图删除的项,那么我们将删除列表其余部分中该元素的下一个出现,如果不是,我们将在列表其余部分重复出现。

(define (remove-2nd item l)
(cond
((null? l) '())
((null? (cdr l)) l)
(else (if (equal? item (car l))
(cons (car l) (remove item (cdr l)))
(cons (car l) (remove-2nd item (cdr l)))))))

在Racket:中使用模式匹配

(define (remove-2nd e l)
(match l
[(or `() `(e)) l]
[(cons f r) (cons f (if (equal? e f) (remove e r) (remove-2nd e r)))]))

一些测试:

(remove-2nd 1 '())
; => '()
(remove-2nd 1 '(1))
; => '(1)
(remove-2nd 1 '(2))
; => '(2)
(remove-2nd 1 '(2 2))
; => '(2 2)
(remove-2nd 1 '(1 1))
; => '(1)
(remove-2nd 1 '(1 2))
; => '(1 2)
(remove-2nd 'c '(a b c d c x c))
; => '(a b c d x c)

一般(尾调用递归(解决方案remove-nth,然后是特殊情况n = 2

(define (remove-nth item l n (test equal?) (acc '()) (counter 1))
(cond
((null? l) (reverse acc))
((test (car l) item) (if (= counter n)
(remove-nth item (cdr l) n test acc (+ counter 1))
(remove-nth item (cdr l) n test (cons (car l) acc) (+ counter 1))))
(else (remove-nth item (cdr l) n test (cons (car l) acc) counter))))
(define (remove-2nd item l (test equal?))
(remove-nth item l 2 test))

最新更新