【问题标题】:How can I recursively check if a list is sorted in Lisp?如何递归检查列表是否在 Lisp 中排序?
【发布时间】:2015-10-09 01:23:35
【问题描述】:

我想编写一个递归函数来检查列表,如果列表是升序,则返回 true,否则返回 NIL。如果列表为空,它仍然是正确的。我对 Lisp 完全陌生,所以它仍然很混乱。

(defun sorted (x)
  (if (null x)
      T
      (if (<= car x (car (cdr x)))
          (sorted (cdr x))
          nil)))

【问题讨论】:

  • 你快到了,但你需要修正语法 [例如(

标签: list recursion lisp common-lisp


【解决方案1】:

递归版本:

(defun sorted (list)
  (or (endp list)
      (endp (cdr list))
      (and (<= (first list) (second list))
           (sorted (cdr list)))))

接受:test 参数的更惯用的基于循环的谓词:

(defun sortedp (list &key (test #'<=))
  (loop for (a b) on list
        while b
        always (funcall test a b)))

接受:key的版本;对于每个访问过的元素,我们只调用一次key 函数:

(defun sortedp (list &key (test #'<=) (key #'identity))
  (loop for x in list
        for old = nil then new
        for new = (funcall key x)
        for holdp = T then (funcall test old new)
        always holdp))

一些测试:

(loop for k in '(() 
                ((1)) 
                ((1) (2)) 
                ((2) (1)) 
                ((1) (2) (3)) 
                ((3) (2) (1)))
      collect (sortedp k :test #'> :key #'car))

=> (T T NIL T NIL T)

这个也适用于其他类型的序列:

(defun sortedp (sequence &key (test #'<=) (key #'identity))
  (reduce (lambda (old x &aux (new (funcall key x)))
            (if (or (eq old t)
                    (funcall test old new))
                new
                (return-from sortedp nil)))
          sequence
          :initial-value t))

以上测试给出:

(T 1 NIL 1 NIL 1)

...由于广义布尔值,这是一个正确的结果。

【讨论】:

  • @AryaAtighehchian 您使用的是哪个环境?你有任何错误信息吗?
  • nvm 我想通了!无论如何你可以帮助我完成其他功能吗?
【解决方案2】:

如果您正在做作业(似乎是这样),那么上面的答案就可以了。如果你刚刚学习 Lisp,并且没有递归的限制,那么下面的内容可能会让你对 Lisp 的强大有一个初步的了解:

(defun sorted (l) 
  (or (null l) (apply #'< l)))

【讨论】:

    【解决方案3】:

    您的解决方案的第一个问题是基本情况您需要不要停在列表的末尾,而是在查看最后一个 to 元素时,因为您需要对元素进行比较。对(car x)的调用中也缺少括号

    (defun sorted (list)
      (if (endp (cddr list))
          (<= (car list) (cadr list))
          (and (<= (car list) (cadr list))
               (sorted (cdr list)))))
    

    请记住,在 CL 中不鼓励递归解决方案

    【讨论】:

    • 这似乎失败了,列表长度为 1。
    猜你喜欢
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-30
    • 2011-09-02
    • 2012-07-20
    • 1970-01-01
    相关资源
    最近更新 更多