为什么这个lisp函数返回nil?

时间:2017-09-11 06:17:21

标签: recursion functional-programming lisp

我正在尝试构建一个lisp函数,该函数将通过列表进行car和cdr,同时将该列表中的值与最大值进行比较。如果列表中的值大于最大值,则该值由最大值替换。我想知道为什么我得到nil的返回值?我是lisp的新手,我来自Java背景,所以它与我完全不同。我不允许使用任何面向对象的东西,我只限于汽车,cdr,追加,缺点。我想返回列表" 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)))))
)

1 个答案:

答案 0 :(得分:0)

格式化&命名

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

  5. 让我们开始修复。首先,让我们处理问题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)正常(最后一个子句),则会将其添加到elements2

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

       (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是否需要简单>就足够了。

    • elements2相比,elements中的项目排序错误(我将其留待您解决)。这是列表上迭代算法的常见问题。

    最后,更多CL的做法是

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

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