使用Lisp:定义一个函数,该函数接受一个列表和一个数字,如果该数字出现在列表中,则返回true

时间:2019-02-27 02:20:17

标签: lisp common-lisp

我不是Lisp的新手,但是我遇到了问题,我试图在列表中找到该号码,但是它不起作用。我还没有做退货声明

(defun num (x 'y)
    (if (member x '(y)) 't nil))

(write (num 10 '(5 10 15 20)))

我的输出仅输出nil而不是执行该功能,我对自己做错了感到困惑。

3 个答案:

答案 0 :(得分:5)

解决方案

(defun member-p (element list)
  "Return T if the object is present in the list"
  (not (null (member element list))))

not / null模式等效于(if (member element list) t nil),但更常见。

实际上,您实际上并不需要此单独的功能, member足够好。

后缀-p代表谓词,请参见。 integerpupper-case-p

您的代码

  1. 您不能引用lambda list元素,因此需要将defun num (x 'y)替换为defun num (x y)
  2. 您不需要引用t
  3. 引用'(y)毫无意义,将其替换为y
  4. 您不需要write函数调用,REPL会为您完成。

另请参见

答案 1 :(得分:2)

几乎可以肯定,您不仅应该使用member,而且要编写一个满足您需要的函数(显然,在现实生活中,您只需要使用member就是因为它的用途)。< / p>

所以。要知道对象是否在列表中:

  • 如果列表为空,则不是;
  • 如果列表的开头等于对象,则为
  • 否则,它在列表的末尾。

您可以将其直接转换为功能:

(defun num-in-list-p (n l)
  ;; is N in L: N is assumed to be a number, L a list of numbers
  (cond ((null l)
         nil)
        ((= n (first l))
         t)
        (t
         (num-in-list-p n (rest l)))))

答案 2 :(得分:1)

您可以使用内置的位置函数,该函数将在列表中返回数字的索引:

(position 1 '(5 4 3 2 1))

如果要定义自己的功能:

CL-USER> (defun our-member(obj lst)
   (if(zerop (length lst))
      nil
      (if(equal(car lst)obj)
      T
     (our-member obj (cdr lst)))))
OUR-MEMBER
CL-USER> (our-member 1 '(5 4 3 2 1))
T
CL-USER> (our-member 99 '(1 2 3 4 5))
NIL

我们可以创建一个称为“我们的成员”的函数,该函数将一个对象(在您的情况下为数字)和一个列表(在您的情况下为数字列表)作为参数。在这种情况下,我们的“基本情况”将是列表的长度是否等于零。如果是,但我们仍未找到匹配项,我们将返回nil。否则,我们将检查列表的汽车(列表中的第一个元素)是否等于我们传递的obj。如果是这样,我们将返回T(true)。但是,如果不是,我们将再次调用该函数,将对象和列表的cdr(列表后面的所有东西)再次传递给该函数,直到列表中没有剩余的项目。如您所见,对该函数的调用的第一个示例返回T,而第二个示例调用返回NIL。

使该实用程序功能成为一个很好的例子的原因是,它实际上也向您显示了成员函数的底层工作以及内部的情况。