Chuong Nguyen
Chuong Nguyen

Reputation: 67

the function to list number in a list

I have a question need your help.

Writing a recursion function named list-number to list every number in list. For example, (list-number '(2 a 4 b)) => (2 4).

Here is my try. But it doesn't work. Could you help me figure out?

     (defun list-number (x)
       (cond ((numberp x) x)
             ((atom x) nil)
             (t (cons (list-number (car x)) (list-number (cdr x))))))

Thanks for your help.

Upvotes: 0

Views: 175

Answers (2)

ccQpein
ccQpein

Reputation: 815

You mean this?

(defvar *test '(2 a 4 b))

(defun list-number (nl)
  (cond ((numberp (car nl))
         (cons (car nl) (list-number (cdr nl))))
        ((eql nil nl)
         nil)
        (t
         (list-number (cdr nl)))))

(list-number *test)
(2 4)

BTW, if you want to write a tail recursive function, I recommend store statue in arguments, like:

(defvar *test '(2 a 4 b))
(defun list-number (head nl)
  (cond ((eql nil nl)
         head)
        ((numberp (car nl))
         (list-number (append head (list (car nl))) (cdr nl)))
        (t
         (list-number head (cdr nl)))))

(list-number '() *test)
(2 4)

Upvotes: 0

Sylwester
Sylwester

Reputation: 48745

You are doing this:

(list-number '(2 a))                           ; ==
(list-number '(2 . (a . ())))                  ; == 
(cons (list-number '2) (list-number '(a . ())) ; ==
(cons (list-number '2)           ; 2 is a number
      (cons (list-number 'a)     ; a is an atom
            (list-number '())))  ; () is an atom ==
(cons 2 (cons nil nil))
; ==> (2 nil)

Your problem is that you cons before you know if it should be a part of the result or not.

How you should do it is:

  1. check if it's the empty list, then result is the empty list
  2. check if the first element is a number. then you cons this number to the recursion of the rest of the list.
  3. if neither two hit then the first element is not supposed to be a part of the result. Just recurse to the rest of the list since it might have numbers as well.

With this logic..

(list-number '(2 . (a . ())))     ; == 
(cons '2 (list-number '(a . ()))) ; ==
(cons '2 (list-number '()))       ; ==
(cons '2 '()) ; ==> (2)

This logic does not handle trees.

Upvotes: 1

Related Questions