Написать функцию, удаляющую из списка каждый k-ый элемент - Lisp

Узнай цену своей работы

Формулировка задачи:

В общем есть задачка: Написать функцию, удаляющую из списка каждый k-ый элемент. Так вот, написал, прекрасно работает:
;Главная функция
(defun fun (x k)
    (cond
        ((null x) nil)
        (T (append (head x k) (fun (tail x k) k)))
    )
)
 
;Берем все элементы до k-го 
(defun head (x k)
    (cond
        ((null x) nil)
        ((= k 0) nil)
        (T (cons (car x) (head (cdr x) (- k 1))))
    )
)
 
;Берем все элементы после k-го
(defun tail (x k)
    (cond
        ((null x) nil)
        ((> k 0) (tail (cdr x) (- k 1)))
        (T (cdr x))
    )
)
И меня интересует вопрос, можно ли ужать этого монстра? А то, как мне кажется можно. Например запихнуть всё в одну функцию? Не используя других стандартных Lisp-функций которые встречаются в коде?

Решение задачи: «Написать функцию, удаляющую из списка каждый k-ый элемент»

textual
Листинг программы
(defun del-every-k (lst k &optional (n 1))
  (cond ((null lst) nil)
        ((= n k) (del-every-k (cdr lst) k 1))
        (t (cons (car lst) (del-every-k (cdr lst) k (+ n 1))))))
 
==> DEL-EVERY-K
 
(del-every-k '(1 2 3 4 5 6 7 8 9 10) 3)
 
==> (1 2 4 5 7 8 10)
 
(del-every-k '(1 2 3 4 5 6 7 8 9 10) 2)
 
==> (1 3 5 7 9)
 
(del-every-k '(1 2 3 4 5 6 7 8 9 10) 1)
 
==> NIL

Объяснение кода листинга программы

В коде определена функция del-every-k. Она принимает три аргумента: lst — список, из которого следует удалить элементы, k — шаг, с которым следует удалять элементы, и n — номер начального элемента, с которого следует начинать удаление (необязательный аргумент, по умолчанию равный 1). Функция использует конструкцию cond для проверки трех условий:

  1. Если lst равен nil, то возвращается nil, так как удалять элементы из пустого списка не имеет смысла.
  2. Если n равно k, то функция вызывает саму себя, но уже с cdr lst (т.е. без первого элемента списка), k и 1 (чтобы начать удаление со следующего элемента после текущего).
  3. Если n не равно k, то возвращается новый список, состоящий из текущего элемента (car lst), за которым следует результат вызова функции с cdr lst, k и n+1 (чтобы продолжить удаление с следующего элемента). Примеры использования функции: — (del-every-k '(1 2 3 4 5 6 7 8 9 10) 3) — удаляет каждый третий элемент из списка, возвращает (1 2 4 5 7 8 10). — (del-every-k '(1 2 3 4 5 6 7 8 9 10) 2) — удаляет каждый второй элемент из списка, возвращает (1 3 5 7 9). — (del-every-k '(1 2 3 4 5 6 7 8 9 10) 1) — удаляет каждый первый элемент из списка, возвращает nil.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.083 из 5
Похожие ответы