首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于检查列表中的值是否不起作用的Lisp递归函数

用于检查列表中的值是否不起作用的Lisp递归函数
EN

Stack Overflow用户
提问于 2019-10-29 05:51:46
回答 3查看 440关注 0票数 0

我正在做一个递归函数,它接受一个列表和一个值ex:'b‘(a.b),如果没有找到,则返回nil,如果找到,则返回t。我的问题是在行(cond ((eq A (car L)) t)中,它似乎在(cond ((and (atom L (eq A L)) t)返回之后检查那个条件。我的印象是,如果满足该条件,执行将停止,函数将返回。有什么办法解决这个问题吗?而且,我只能使用原语函数functions car cdr运算符+,-,<,和> null eq listp atom symbolp

代码语言:javascript
复制
;test cases 
(checkInner 'b '(a . b))
(checkInner 'f '(c e f))
(checkInner 'b '(b))

;function 
(defun checkInner(A L)
    (cond ((and (atom L) (eq A L)) t)
    )
    (cond ((or (atom L) (eq A L)) nil)
    )
    (cond ((eq A (car L)) t)
            (t (checkInner A (cdr L))
            )
    )
)
EN

回答 3

Stack Overflow用户

发布于 2019-10-29 06:00:12

除非使用显式(return-from checkInner value)表达式,否则函数将返回其上一个表达式的值。因此,函数返回的惟一值是最后一个cond表达式;前两个测试被忽略。

您需要将所有案例组合到一个COND表达式中。

另外,第二个测试不应该使用or。如果L是一个原子,它将不等于L,因为我们在前面的例子中测试了它。

代码语言:javascript
复制
(defun checkInner(A L)
    (cond ((and (atom L) (eq A L)) t)
          ((atom L) nil)
          ((eq A (car L)) t)
          (t (checkInner A (cdr L)))))
票数 3
EN

Stack Overflow用户

发布于 2019-10-29 05:59:26

所以我修复了它,感谢你确认Barmer,这是我的解决方案

代码语言:javascript
复制
(defun checkInner(A L)
    (cond ((and (atom L) (eq A L)) t)
        (t  (cond ((or (atom L) (eq A L)) nil)
                (t (cond ((eq A (car L)) t)
                        (t (checkInner A (cdr L))
                        )
                    )
                )
            )
        )
    )
)
票数 0
EN

Stack Overflow用户

发布于 2019-11-24 06:22:30

@Barmar你基本上检查了两次L是一个原子,第一次可以写成(( atom L) (eq A L)) (eq A L)返回一个布尔值,所以你不需要显式地从那个子句返回T,这总体上与你的第二个子句((atom L) nil)相矛盾。还要注意,这种解决方案不适用于嵌套的元素列表(这将是唯一愿意编写自己的递归函数的参数,而不仅仅是使用Lisp函数来测试成员资格,如memberfind等)。

代码语言:javascript
复制
(checkInner 'b '(a (c (d (b))))) ; => NIL

下面是一个适用于嵌套列表的递归定义。请注意,您还可以提供一个相等测试函数,以允许您的X具有不同的类型。

代码语言:javascript
复制
(defun check-inner (x coll &key (test #'eq))
   "Check if X is in the collection. Works on nested lists 
and uses the test keyword argument for equality checking."
   (cond
    ((null coll) nil)
    ((listp (car coll)) (or (check-inner x (car coll) :test test)
                            (check-inner x (cdr coll) :test test)))
    ((atom (car coll)) (or (funcall test x (car coll))
                           (check-inner x (cdr coll) :test test)))
    (t (check-inner x (cdr coll :test test)))))

现在你正在寻找的东西也可以隐藏在列表的嵌套层中:

代码语言:javascript
复制
(check-inner 'b '(a (c (d (b))))) ; => T

检查其他类型也没有问题:

代码语言:javascript
复制
(check-inner "b" '(a (c (d ("b")))) :test #'string=) ; => T
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58598863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档