【问题标题】:A complex Lisp issue一个复杂的 Lisp 问题
【发布时间】:2014-11-02 17:24:36
【问题描述】:

定义一个函数contains,它接受两个参数,一个符号A和一个符号列表L,并且仅当L包含A作为其元素之一时才返回t。

这是最初的问题。我对 LISP 很陌生,想要一些代码以及语法解释。来自 java 和 C++ 背景的 LISP 在本质上是非常不同的。请帮忙。

到目前为止,我的代码成功地将两个输入作为参数。

伪代码: 我将 A 中的值与列表的第一个值进行比较,然后通过递归调用将列表和变量 A 传递回函数,直到列表为空。如果 List 为空,则返回 null。

这个问题是如果 List 包含一个嵌套列表,我如何识别嵌套循环。

如:(contains #\b '(a (((b))) c)) -> 必须打印为真。

到目前为止我有什么代码:

(defun contains (a list)
    (if (eq a(car list))
        (princ "t")
        (contains a (cdr list))))

(contains  #\B '(B a c d e f g))

我需要一种在列表末尾进行检测的方法。还有一种在嵌套列表中搜索的方法。

【问题讨论】:

  • 我假设你不允许使用标准的MEMBER函数?
  • 这个问题不需要你进入嵌套列表。
  • 很遗憾没有,我只能使用原始函数,例如 defun, car cdr cons if
  • 问题定义说L是一个符号列表。 (a (((b))) c) 不是符号列表,而是符号列表、列表和另一个符号。
  • 这是一个示例列表。该函数也扫描嵌套列表中的变量,然后跳回外部列表并继续扫描外部列表。它还必须扫描所有嵌套列表。

标签: lisp


【解决方案1】:

首先让我们纠正一些错误:#\b 不是符号,而是字符,据我了解,我们在符号列表中寻找符号,所以我们不需要做一些字符 ->符号转换。第二:不要(princ t)只返回t。

我的短变体:

(defun contains (sym nested-list)
  "Find if NESTED-LIST contains a SYM"
  ;; Check if our list is CONS-cell?.
  (if (consp nested-list)
    ;; Recursion on cars and cdrs
    (or (contains sym (car nested-list))
        (contains sym (cdr nested-list)))
    ;; Elseway just check for equality
    (eq sym nested-list)))

CL-USER> (contains 'a '(b c (x b y (f a)) d))
T
CL-USER> (contains 'w '(b c (x b y (f a)) d))
NIL

也在你的测试用例上:

CL-USER> (contains 'b '(a (((b))) c))
T

【讨论】:

  • 关键字 consp 有什么作用?
  • @AdityaNishtala,我在代码中添加了一些 cmets,CONSP 检查它是否是一个 CONS-CELL 参数。所以我们基本上通过列表。如果我们有一个嵌套列表,我们进入它,如果我们在这里有一个原子,我们只是检查与我们的符号是否相等。而consp 不是关键字,它只是一个函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-09
  • 2015-06-11
  • 1970-01-01
相关资源
最近更新 更多