如何在列表中找到原子的位置

时间:2011-11-08 15:23:37

标签: lisp common-lisp

我试图在列表中找到原子的位置。

(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 个答案:

答案 0 :(得分:1)

首先,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运行它们。)

其次,不要听起来比你更神圣,但你的括号样式只会伤到我的眼睛。将一个左括号放在列表中第一个东西的前面,并且所有关闭的parens与列表中的最后一个东西在同一行上。例如:

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

最终,如果在letter中找不到list,则返回NIL,如果是,则返回索引。是的,我知道那些parens看起来不透明,但这就是Lisp的编写方式。你会习惯的。

tl; dr在标准库中使用position;它做你想做的。

答案 1 :(得分:1)

这是另一种仅使用递归的解决方案:

(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) =在所有重复之后,如果列表为空,则返回nil

((equal letter (car liste)) 0) =如果找到我们要找的字母,它会返回0并开始取消堆叠

((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste)))) =只有在尚未查看整个列表的情况下才会添加+1,所以只有在我们之前找到了我们的信件时

答案 2 :(得分:0)

这是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 here)中的等价物,它有一个很好的构造设计用于此(并且当然也消除了尾部调用作为语言规范的一部分):

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