Каждое другое письмо в списке? Лисп

Я относительно новичок в 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 ответов

Решение

Поскольку вы говорите, что хотите, чтобы это было сделано рекурсивно, просто продумайте это в каждом конкретном случае.

  1. Список нулевой -> вернуть пустой список [пустой список '()].
  2. В противном случае список не равен нулю -> В этом случае вы хотите создать новый список, содержащий первый элемент, пропустить второй элемент, а затем захватить все остальные элементы оставшегося списка.

Превращение этого анализа случая в код выглядит примерно так:

(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)))))
Другие вопросы по тегам