【问题标题】:How to find the position of an atom in list如何在列表中找到原子的位置
【发布时间】:2011-11-08 15:23:37
【问题描述】:

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

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

【问题讨论】:

    标签: lisp common-lisp


    【解决方案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 运行了这些输出。)

    其次,不要听起来比你更神圣或其他任何东西,但你的括号风格只会伤害我的眼睛。在列表中的第一件事前面放一个左括号,所有右括号与列表中的最后一个事物在同一行。例如:

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

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

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

    【讨论】:

      【解决方案2】:

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

      (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) = 全部recusion后,如果列表为空,则返回nil

      ((equal letter (car liste)) 0) = 如果找到我们要找的字母,它返回 0 并开始拆垛

      ((position-in-list letter (cdr liste)) (+ 1 (position-in-list letter (cdr liste)))) = 仅在尚未遍历整个列表时才添加+1,因此只有在我们之前找到了我们的信时才添加+1

      【讨论】:

        【解决方案3】:

        这是 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))])))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-07-13
          • 1970-01-01
          • 2017-10-02
          • 2020-04-15
          • 1970-01-01
          • 1970-01-01
          • 2021-12-19
          相关资源
          最近更新 更多