Написать функцию, удаляющую из списка каждый k-ый элемент - Lisp
Формулировка задачи:
В общем есть задачка:
Написать функцию, удаляющую из списка каждый k-ый элемент.
Так вот, написал, прекрасно работает:
И меня интересует вопрос, можно ли ужать этого монстра? А то, как мне кажется можно. Например запихнуть всё в одну функцию? Не используя других стандартных Lisp-функций которые встречаются в коде?
;Главная функция (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)) ) )
Решение задачи: «Написать функцию, удаляющую из списка каждый 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
для проверки трех условий:
- Если
lst
равенnil
, то возвращаетсяnil
, так как удалять элементы из пустого списка не имеет смысла. - Если
n
равноk
, то функция вызывает саму себя, но уже сcdr lst
(т.е. без первого элемента списка),k
и1
(чтобы начать удаление со следующего элемента после текущего). - Если
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
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д