Каждое другое письмо в списке? Лисп
Я относительно новичок в LISP и пробую что-то новое для программы на Лиспе, которую пытаюсь создать для презентации.
Мне нужно иметь возможность печатать любой другой символ в списке, например, (A B C D E F) будет возвращаться (A C E) .. но я легко запутался...
Я обычно программирую на Java, так что для меня это немного другое.
Я пытаюсь запрограммировать это, используя чисто рекурсию.. Так что-то вроде....
(defun every-other (lst)
(cond ((null lst) 0)
(( **** now this is where I get confused as to what I should do..
I've tried adding a counter to only remove even numbered elements, but I think I implemented the counter wrong, I also tried remove(cadr lst) lst, but that would only return zeros...
любая помощь будет принята с благодарностью..
Спасибо!
5 ответов
Поскольку вы говорите, что хотите, чтобы это было сделано рекурсивно, просто продумайте это в каждом конкретном случае.
- Список нулевой -> вернуть пустой список [пустой список '()].
- В противном случае список не равен нулю -> В этом случае вы хотите создать новый список, содержащий первый элемент, пропустить второй элемент, а затем захватить все остальные элементы оставшегося списка.
Превращение этого анализа случая в код выглядит примерно так:
(defun every-other (lst)
(cond
;; If the list is null return the empty list.
((null lst) '())
;; If the list is not null, construct [cons] a new list with the first element of lst
;; and every-other element of the list after the first two elements [rest returns the
;; list without the first element, so we can just use it twice].
(t (cons (first lst) (every-other (rest (rest lst)))))))
Теперь процесс оценки этого кода должен выглядеть примерно так:
(every-other '(a b c d e f))
=> (cons 'a (every-other '(c d e f)))
=> (cons 'a (cons 'c (every-other '(e f))))
=> (cons 'a (cons 'c (cons 'e (every-other '())))
=> (cons 'a (cons 'c (cons 'e '())))
=> (cons 'a (cons 'c '(e)))
=> (cons 'a '(c e))
=> '(a c e)
Просто используйте петлю.
(loop :for c :in '(a b c d e f) :by #'cddr
:collect c)
:By
в for
-in
предложение устанавливает пошаговую функцию (по умолчанию #'cdr
). Чтобы получить любой другой элемент, делайте два шага каждый раз. Cddr
это ярлык для применения cdr
два раза.
Для развлечения loop
решение на основе:
(defun every-other (lst)
(loop
for i in lst
for keep = t then (not keep)
if keep collect i))
(defun aaa (x)
(aa (length x) x))
(defun aa (n x)
(cond ((null x) nil)
((evenp (- n (length x))) (cons (car x) (aa n (cdr x))))
(t (aa n (cdr x)))))
Это глупый случай, лол ~
Короче рекурсивное решение:
(defun every-other (l)
(unless (null l)
(cons (first l) (every-other (cddr l)))))