Cómo encontrar la posición de un átomo en la lista

Estoy tratando de encontrar la posición de un átomo en la lista.

(position-in-list 'a (a b c d e)) da 0

(position-in-list 'b (a b c d e) ) da 1

(position-in-list 'Z(a b c d e) ) da nada.

He pegado mi código que solo devuelve 1.

(defun position-in-list (letter list) )
( cond
( (null list) nil
)
( (eq (car list) letter) count 
)
( t (position-in-list letter (cdr list)) count)
)
)

( defun count ()
( + 0 1)
)

preguntado el 08 de noviembre de 11 a las 15:11

3 Respuestas

En primer lugar, la biblioteca estándar Common Lisp ya lo tiene; se llama position.

(position 'a '(a b c d e)) ==> 0
(position 'b '(a b c d e)) ==> 1
(position 'z '(a b c d e)) ==> NIL

En general, las cosas de la biblioteca estándar están ahí para ser utilizadas. (Sí, position da esos resultados. Acabo de pasarlos a través de un REPL).

En segundo lugar, no quiero sonar más santo que tú ni nada, pero tu estilo de paréntesis me duele los ojos. Coloque un paréntesis de apertura justo delante de la primera cosa en la lista, y todos los paréntesis de cierre en la misma línea que la última cosa en la lista. Por ejemplo:

(defun hello-world ()
    (format t "Hello World!"))

or

(defun position-in-list (letter list)
  (cond
    ((null list)            nil)
    ((eq (car list) letter) count)
    (t                      (position-in-list letter (cdr list))
                            count)))

(defun count ()
  (+ 0 1))

Esto puede ser difícil para tus ojos [lo fue para mí al principio], pero te ayuda a encontrar errores más fácilmente.

En tercer lugar, no sé cuál es tu count Se supone que la función está haciendo, pero position-in-list probablemente no lo esté haciendo de la manera esperada. Prueba esto:

(defun position-in-list (letter list)
  (cond
    ((null list)            nil)
    ((eq (car list) letter) 0)
    (t                      (1+ (position-in-list letter (cdr list))))))

En última instancia, devuelve NIL si letter no se encuentra en list, o el índice si lo es. Sí, sé que esos parens se ven opacos, pero así es como está escrito Lisp. Te acostumbrarás.

tl; dr Use position en la biblioteca estándar; hace lo que quieres.

respondido 26 mar '12, 14:03

Aquí hay otra solución que usa solo recursividad:

(defun position-in-list (letter liste)
   (cond
      ((atom liste) nil)
      ((equal letter (car liste)) 0)
      ((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste)))) ) )

((atom liste) nil) = después de toda la recusión, si la lista está vacía, devuelve nulo

((equal letter (car liste)) 0) = si encuentra la letra que estamos buscando, devuelve 0 y comienza a desapilar

((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste)))) = agrega +1 solo si aún no hemos revisado toda la lista, por lo que solo si hemos encontrado nuestra carta antes

Respondido 07 Feb 17, 12:02

Aquí hay una versión recursiva de cola en CL:

(defun position-in-list (elt list &key (test #'eql))
  (labels ((pill (tail p)
             (cond ((null tail) nil)
                   ((funcall test elt (first tail)) p)
                   (t (pill (rest tail) (1+ p))))))
    (pill list 0)))

Y el equivalente en Scheme (Racket aquí), que tiene una construcción agradable diseñada solo para esto (y también elimina las llamadas finales como parte de la especificación del lenguaje, por supuesto):

(define (position-in-list elt lst #:test (test eqv?))
  (let pill ([tail lst] [p 0])
    (cond [(null? tail) #f]
          [(test elt (first tail)) p]
          [else (pill (rest tail) (+ p 1))])))

Respondido 07 Feb 17, 14:02

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.