Как найти позицию атома в списке - PullRequest
0 голосов
/ 08 ноября 2011

Я пытаюсь найти положение атома в списке.

(position-in-list 'a (a b c d e)) дает 0

(position-in-list 'b (a b c d e) ) дает 1

(position-in-list 'Z(a b c d e) ) дает ноль.

Я вставил свой код, который возвращает только 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)
)

Ответы [ 3 ]

1 голос
/ 06 февраля 2017

Вот еще одно решение, использующее только рекурсию:

(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) = после всех отказов, если список пуст, возвращается ноль

((equal letter (car liste)) 0) = если он находит букву, которую мы ищем, он возвращает 0 и начинает unstacking

((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste)))) = добавляет +1 только в том случае, если еще не прошел весь список, поэтому только в том случае, если мы нашли наше письмо до этого

1 голос
/ 26 марта 2012

Во-первых, стандартная библиотека Common Lisp уже имеет это;он называется 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

В общем, вещи в стандартной библиотеке должны быть использованы.(Да, position дает эти результаты. Я только что проверил их через REPL.)

Во-вторых, не для того, чтобы казаться более святым, чем что-либо, но ваш стиль скобок просто ранит мои глаза.Поместите открывающую скобку прямо перед первой вещью в списке, и все закрывающие скобки в той же строке, что и последняя вещь в списке.Например:

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

или

(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))

Это может быть неприятно для ваших глаз [это было для меня сначала], но это помогает вам легче находить ошибки.

В-третьих, я не знаю, что должна делать ваша count функция, но, вероятно, position-in-list делает это не так, как вы ожидаете.Попробуйте это:

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

В конечном итоге, возвращает NIL, если letter не найден в list, или индекс, если он есть.Да, я знаю, что эти парены выглядят непрозрачными, но так написано на Лиспе.Вы привыкнете к этому.

tl; dr Используйте position в стандартной библиотеке;он делает то, что вы хотите.

0 голосов
/ 07 февраля 2017

Вот хвосто-рекурсивная версия в 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)))

И эквивалент в Scheme (Racket здесь), который имеет приятную конструкцию, предназначенную именно для этого (а также исключает хвостовые вызовы как частьспецификация языка, конечно):

(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))])))
...