Вопрос

У меня есть основная функция клиппа, которую я делаю, которая просто возвращает количество атомов в списке. Проблема, которая у меня есть, заключается в том, что мне нужно, чтобы он увеличивал атомы в списке, который находится в списке, вместо того, чтобы увидеть список как 1 элемент в списке.

Реальный вопрос, который я думаю, Как вы дифференцируете в своем коде, является ли элемент списком или атом? Если я могу сделать это, я могу прислать списки другую функцию, чтобы добавить и вернуть количество атомов, которые они содержат.

Ясно как грязь? :)

У меня есть пример здесь:

(defun list_length (a)
  (cond ((null a) 0)
        (t (+ 1 (list_length (cdr a))))))

Это отлично работает, если в родительском списке нет встроенных списков, например,'(1 2 3 (4 5) 6) Вернут 5. Мне нужно, чтобы он включил 4 и 5 вместо списка (4 5) в качестве одного.

Спасибо за вашу помощь.

Джон


РЕДАКТИРОВАТЬ:

(defun list_length (a)
  (cond ((null a) 0)
        ((listp (car a)) (list_length (car a)))
        (t (+ 1 (list_length (cdr a))))))

[18]> (list_length '(1 2 3 (4 5) 6))
1. Trace: (LIST_LENGTH '(1 2 3 (4 5) 6))
2. Trace: (LIST_LENGTH '(2 3 (4 5) 6))
3. Trace: (LIST_LENGTH '(3 (4 5) 6))
4. Trace: (LIST_LENGTH '((4 5) 6))
5. Trace: (LIST_LENGTH '(4 5))
6. Trace: (LIST_LENGTH '(5))
7. Trace: (LIST_LENGTH 'NIL)
7. Trace: LIST_LENGTH ==> 0
6. Trace: LIST_LENGTH ==> 1
5. Trace: LIST_LENGTH ==> 2
4. Trace: LIST_LENGTH ==> 2
3. Trace: LIST_LENGTH ==> 3
2. Trace: LIST_LENGTH ==> 4
1. Trace: LIST_LENGTH ==> 5
5
[19]> (dribble)
Это было полезно?

Решение

(listp foo) вернется t если foo это список и nil в противном случае.

Итак, вы можете сделать свой list_length Функция обработки вложенных списков, добавив следующий случай в ваш cond:

((listp (car a)) (+ (list_length (car a)) (list_length (cdr a))))

Другие советы

АТОМ это предикат, который вы просите.

Я рекомендую использовать Flatten, стандартную рутину для сглаживания списков в списках - я представляю одну реализацию здесь.

(defun flatten (x)
  "descend into the supplied list until an atom is hit.
append the atom to the flattened rest"
  (if (endp x)
      x
    (if (atom (car x ))
    (append (list (car x)) (flatten (cdr x)))
      (append (flatten (car x)) (flatten (cdr x ))))))

Flatten Возвращает список: Вы можете запустить длину в списке, чтобы увидеть, сколько атомов вы завели.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top