【问题标题】:Remove a specific item in a list?删除列表中的特定项目?
【发布时间】:2016-01-29 00:24:32
【问题描述】:

我想先说是的,这是我正在处理的家庭作业问题,我不想要实际的答案,也许只是朝着正确的方向轻推。 Anyhoo,我正在上编程语言结构的课程,我们的一个项目是用 lisp 编写各种小程序。这需要用户输入一个列表和一个原子,然后从列表中删除原子的所有实例。我在网上搜遍了,没有找到那么多好的 lisp 资源,所以我向大家求助。

不管怎样,我们的教授给我们的东西很少,我几乎没有什么意思。

这是我目前所拥有的,但它不起作用。

(defun removeIt (a lis)
  (if (null lis) 0
      (if (= a (car lis))
          (delete (car lis))
          (removeIt (cdr lis)))))

当我输入 (removeIt 'u '(u e u e)) 作为输入,它给了我一个错误,说明它在需要 2 时得到了 1 个参数。我犯了什么错误?

【问题讨论】:

    标签: list lisp common-lisp


    【解决方案1】:

    这是递归函数的一个很好的例子。假设已经存在一个名为 my-remove 的函数,它接受一个原子和一个列表作为参数,并返回没有给定原子的列表。所以 (my-remove 'Y '(X Y Z)) => '(X Z) 现在,当您有另一个列表(A X Y Z)而不是列表'(X Y Z)时,您将如何使用此函数,即前面有一个元素A? 您可以将 A 与您的 atom 进行比较,然后根据元素 A 是否与您的 atom 匹配,您可以将此元素 A 添加到将 remove 应用于列表的其余部分的结果中。 通过这种递归,函数 my-remove 将使用较短的列表连续调用。现在你只需要考虑基本情况,即当列表为空时函数 my-remove 必须返回什么。

    【讨论】:

      【解决方案2】:

      首先,一些外观变化:

      (defun remove-it (it list)
        (if (null list) 0
            (if (= it (car list))
                (delete (car list))
                (remove-it (cdr list)))))
      

      描述性和自然的标识符名称在 CL 社区中是首选的。不要害羞地使用像list 这样的名字——CL 有多个命名空间,所以你不必担心太多的冲突。使用连字符代替驼峰式大小写或下划线。另外,read a short style guide.

      你说你想要的不是答案而是有用的提示,所以我们开始吧:

      • 检查您的基本情况 - 您的结果将是一个列表,那么为什么要返回一个数字?

      • 使用适当的比较函数 - = 仅用于数字。

      • 你正在建立一个新的结果列表,所以不需要delete 任何东西——只是不要添加你不想要的东西。

      • 但请记住添加您想要的内容 - 通过consing 将您想要保留的内容添加到将您的函数应用于列表的其余部分的结果中来构建您的结果列表。

      • 如果您不想保留某个元素,请继续将您的函数应用于列表的其余部分。

      • 您将函数定义为接受两个参数,但您仅使用(cdr list) 调用它。提供缺少的参数。

      我搜索了互联网并没有找到那么多好的 lisp 资源,

      哦,来吧。

      无论如何,我推荐Touretzky.

      顺便说一句,您尝试实现的功能是built-in,但您的教授可能不会接受它作为解决方案,并且自己动手是一个很好的练习。 (要获得额外的功劳,请尝试解决嵌套列表。)

      【讨论】:

        【解决方案3】:

        这是专门寻找 elisp 的其他人的答案。为此目的存在一个名为 delq 的内置函数

        例子

        (setq my-list '(0 40 80 40 90))   ;; test list
        (delq 40 my-list)                 ;; (0 80 90)
        

        如果你从源代码安装了 emacs,你可以通过 Mx find-function delq 查看它是如何实现的

        【讨论】:

        猜你喜欢
        • 2022-01-08
        • 2019-03-17
        • 2018-05-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多