2017-01-25 3 views
1

Я хочу создать функцию, которая сглаживает список и удаляет весь потенциал nil внутри.Сглаживание списков (при удалении «nil» и удержании атомов после «.») В lisp

Ожидаемое поведение, пример 1:

(myfunc '(a (b (c) (d)) (e f) (g (h)) nil)) => (a b c d e f g h) 

Ожидаемое поведение, пример 2:

(myfunc '(a . d)) => (a d) 

моя функция до сих пор:

(defun myfunc (l) 
    (cond 
     ((atom l) nil) 
     ((and (atom (car l)) (not (equal (car l) nil))) (cons (car l) (myfunc (cdr l)))) 
     (t (append (myfunc (car l)) (myfunc (cdr l)))))) 

Моя функция работает, как ожидалось для первого пример, но не второй. я получаю:

(myfunc '(a . d)) => (a) 
  1. Почему это не держать, что d?

  2. Есть ли способ исправить это?

+0

То, как исправить это, чтобы пройти через ваш код с неисправной например, строка за строкой. Это займет около двух минут, и вы начнете создавать ощущение связанных списков и минусов и cdr, в то же время вы увидите, как это происходит. – kennytilton

ответ

2

Может быть, вы должны думать о том, что функция Flatten должна делать, на простом английском языке:

  1. Базовый случай: Если уплощение nil, возвращает пустой список.
  2. Базовый корпус: если сплющивать отдельные атомы, верните список, содержащий именно это.
  3. Рекурсивный футляр: если сплющивать пары, верните список, добавляющий уплощение его car с уплощением его cdr.

Вот как я бы реализовать описание я просто дал:

(defun flatten (x) 
    (cond ((null x) x) 
     ((atom x) (list x)) 
     (t (nconc (flatten (car x)) (flatten (cdr x)))))) 
+0

Спасибо! Не могли бы вы описать, что делает nconc? Я прочитал документ здесь http://clhs.lisp.se/Body/f_nconc.htm, но мне все еще не так ясно. Еще раз спасибо! –

+0

похоже, что я получаю тот же результат, если я заменил «nconc» на «append» на последней строке, не так ли? –

+2

не consp = atom –

Смежные вопросы