Recursion 使用LISP递归查找列表中的元素位置

Recursion 使用LISP递归查找列表中的元素位置,recursion,functional-programming,lisp,Recursion,Functional Programming,Lisp,我的问题是:在不使用MEMBER的情况下,完成以下递归函数的定义 这样,如果L是一个列表,E是L的一个元素,那么(POS E L)返回第一个元素的位置 E在L中出现,如果E不是L的一个元素,则(位置E L)返回0。这是我们提出的解决方案: (DEFUN POS (E L) (COND ((ENDP L) 0) ((EQUAL E (CAR L)) 1 ) (T (+ 1 (POS E (CDR L)) ) ))) 如果我要查找的元素在列表中,则该算法工作正常。我的问

我的问题是:
在不使用MEMBER的情况下,完成以下递归函数的定义 这样,如果L是一个列表,E是L的一个元素,那么(POS E L)返回第一个元素的位置 E在L中出现,如果E不是L的一个元素,则(位置E L)返回0。

这是我们提出的解决方案:

(DEFUN POS (E L)
(COND ((ENDP L)  0)
((EQUAL E (CAR L)) 1 )
(T 
      (+ 1 (POS E (CDR L)) )   

  )))
如果我要查找的元素在列表中,则该算法工作正常。我的问题是,当元素不在列表中时,我将获得列表的长度

例如:

list[1,2,3,4] Find: 5  will reurn 4
如果找不到元素,如何使其返回0。由于是函数式编程,我不能使用循环或变量

您总是返回
(+1)
。但是如果递归结果为零呢?在计算结果之前,应该检查返回值

  • 如果发现一个事件,请返回1
  • 如果找不到结果,则递归计算,从而得到R
  • 如果R为零,则返回零
  • 否则,返回R+1

另一方面,常见的Lisp方式是:

(or (position E L :test #'equal) 0)
您总是返回
(+1)
。但是如果递归结果为零呢?在计算结果之前,应该检查返回值

  • 如果发现一个事件,请返回1
  • 如果找不到结果,则递归计算,从而得到R
  • 如果R为零,则返回零
  • 否则,返回R+1

另一方面,常见的Lisp方式是:

(or (position E L :test #'equal) 0)

正如@coredump所解释的,问题在于,即使没有找到元素,也总是在结果中添加1。我将通过向函数
POS
添加一个额外参数来跟踪列表中的当前位置:

(defun pos (element list &optional (start 0))
  (cond ((endp list) 0)
        ((equal element (first list)) (1+ start))
        (t (pos element (rest list) (1+ start)))))
测试:

(pos 'a '(b a c d a))
2

(pos 'a '(a d a f g))
1

(pos 'w '(a b c d e f))
0
还有一个额外的好处:由于递归调用处于尾部调用位置,该函数生成迭代过程(但是,ANSI Common Lisp不保证它会进行尾部调用优化!好吧,CLisp不会这样做;SBCL和CCL会对优化的代码进行优化,请参阅)。更惯用的通用Lisp解决方案是使用
循环

(defun pos (element list)
  (loop for x in list
     counting x into pos
     when (equal element x)
     return pos
     end
     finally (return 0)))

正如@coredump所解释的,问题在于,即使没有找到元素,也总是在结果中添加1。我将通过向函数
POS
添加一个额外参数来跟踪列表中的当前位置:

(defun pos (element list &optional (start 0))
  (cond ((endp list) 0)
        ((equal element (first list)) (1+ start))
        (t (pos element (rest list) (1+ start)))))
测试:

(pos 'a '(b a c d a))
2

(pos 'a '(a d a f g))
1

(pos 'w '(a b c d e f))
0
还有一个额外的好处:由于递归调用处于尾部调用位置,该函数生成迭代过程(但是,ANSI Common Lisp不保证它会进行尾部调用优化!好吧,CLisp不会这样做;SBCL和CCL会对优化的代码进行优化,请参阅)。更惯用的通用Lisp解决方案是使用
循环

(defun pos (element list)
  (loop for x in list
     counting x into pos
     when (equal element x)
     return pos
     end
     finally (return 0)))

代码格式不正确:-(代码格式不正确):-(谢谢!你是个救命恩人。我花了几个小时试图得到它,但你的解释很有意义。非常感谢。谢谢!你是个救命恩人。我花了几个小时试图得到它,但你的解释很有意义。非常感谢。