【问题标题】:Why does this lisp function return nil?为什么这个 lisp 函数返回 nil?
【发布时间】:2018-02-19 07:37:28
【问题描述】:

我正在尝试构建一个 lisp 函数,该函数将 car 和 cdr 通过一个列表,同时将该列表中的值与最大值进行比较。如果列表中的某个值大于最大值,则该值将被最大值替换。我想知道为什么我得到 nil 的返回值?我是 lisp 的新手,我来自 Java 背景,所以对我来说完全不同。我不允许使用任何面向对象的东西,我仅限于 car、cdr、append、cons。我想返回列表“elements2”。

(defun enforce-upper-limit(maxVal elements elements2)
(when elements
(cond ((greaterThanMax (car elements) maxVal)(enforce-upper-limit maxVal (cdr lst) (append (maxVal))))
(t   (enforce-upper-limit maxVal (cdr elements)(append (car elements)))))
)

)

【问题讨论】:

  • 请格式化并缩进您的代码。您的代码几乎无法阅读。如果您提出问题,您还应该提供可重复的示例和错误消息。查看帮助:stackoverflow.com/help/mcve
  • 你对(append (maxVal))有什么期望,elements2的目的是什么?
  • 请阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。
  • 善待。他开始了。

标签: recursion functional-programming lisp


【解决方案1】:

格式和命名

Common Lisp 不区分大小写,因此您的 maxValgreaterThanMax 将变得不可读。使用- 分隔名称的各个部分并将所有内容设为小写。

空格:左括号前面应该有一个空格。

缩进:这个有各种规则,但长话短说:Lisp 模式下的 Emacs 会在 <Tab> 上做正确的事情

最后,不要让行太长,通常 80 个字符的规则几乎是通用的。

整理后如下图:

(defun enforce-upper-limit (max-val elements elements2)
  (when elements
    (cond ((greater-than-max (car elements) max-val)
           (enforce-upper-limit max-val (cdr lst) (append (max-val))))
          (t (enforce-upper-limit max-val (cdr elements)
                                          (append (car elements))))))

代码中的问题

一些明显的问题:

  1. 第 4 行:表达式 (max-val) 将调用一个名为 max-val 的函数,不带任何参数。我怀疑这就是你想要的。

  2. 函数append 追加列表。在这两种使用情况下,它既没有给出要追加的列表,也没有要追加的列表。

  3. 函数enforce-upper-limit 最多返回nil

  4. 什么是lst?应该是elements

让我们开始修复吧。首先,我们来处理问题3。当elementsnil时,答案应该累积在elements2中。此外,整个条件表达式类似于if... elseif ... 模式。所以,让我们试着把它整理成一个cond

(defun enforce-upper-limit (max-val elements elements2)
  (cond ((null elements) elements2)
        ((greater-than-max (car elements) max-val)
         (enforce-upper-limit max-val (cdr lst) (append (max-val))))
        (t (enforce-upper-limit max-val (cdr elements)
                                        (append (car elements)))))

接下来,让我们看看我们真正想要实现的目标。第二条规定如果(car elements) 太大,则max-val 应该转到elements2。如果(car elements) 是OK(最后一个子句),则添加到elements2

向列表中添加一项是cons 的工作,而不是append。在这两种情况下,我们都使用elements2,所以表达式应该看起来像(cons something elements2)。此外,用elements 替换lst 会产生(几乎)正确的程序:

   (defun enforce-upper-limit (max-val elements elements2)
      (cond ((null elements) elements2)
            ((greater-than-max (car elements) max-val)
             (enforce-upper-limit max-val
                                  (cdr elements)
                                  (cons max-val elements2)))
            (t (enforce-upper-limit max-val (cdr elements)
                                            (cons (car elements) elements2)))))

其他问题

  • 不确定greater-than-max 是否需要,因为简单的> 就足够了。

  • elements 相比,elements2 中的项目顺序错误(我让您自己解决)。这是列表上的迭代算法的常见问题。

最后,更多的 CL 方法是

(defun enforce-upper-limit (list max-val)
  (loop for x in list
        if x > max-val
          collect max-val
        else
          collect x))

但您的作业可能无法接受。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 2016-03-21
    • 2018-01-28
    相关资源
    最近更新 更多