Удалить второе вхождение данного элемента из списка - Ракетка - PullRequest
0 голосов
/ 25 февраля 2020

Мне нужно написать функцию с именем 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' (ab c d c x c)) возвращает (abd c x c), когда я должен получить (ab c dx c).

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Для пустых и одноэлементных списков мы просто возвращаем список. В противном случае мы видим, совпадает ли первый элемент в списке с элементом, который мы пытаемся удалить. Если это элемент, который мы пытаемся удалить, то мы удаляем следующее вхождение этого элемента в остальной части списка, если нет, мы повторяем в остальной части списка.

(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)
0 голосов
/ 25 февраля 2020

Общее (рекурсивное) хвостовое решение 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))
...