【问题标题】:Lisp Insert Sorting ProblemLisp 插入排序问题
【发布时间】:2011-07-18 21:20:58
【问题描述】:

使用 insert 编写一个函数 sort1,它将整数列表按升序排序。 [如果列表为零,我们就完成了。否则将列表的汽车插入排序后的 cdr。]

这是我设法做到的,我无法在一个名为 sort1 的函数中定义这两个函数:

(defun insert (item lst &optional (key #'<))
  (if (null lst)
    (list item)
  (if (funcall key item (car lst))
          (cons item lst) 
          (cons (car lst) (insert item (cdr lst) key)))))
(defun insertion-sort (lst &optional (key #'<))
  (if (null lst)
    lst
    (insert (car lst) (insertion-sort (cdr lst) key) key)))

【问题讨论】:

  • 哇,这是我们的第一个递归问题标题吗?

标签: insert lisp


【解决方案1】:

将所有内容整合到一个函数定义中的最简单方法是使用labels 将函数insert 定义为insertion-sort 中的本地函数。

不过,关于您的代码,还有其他几件事要说:

  • 您无需将变量重新拼写为 lst,以免与函数 list 发生冲突:在 Common Lisp 中,函数和变量位于不同的命名空间中。
  • 通常的做法是将模式(if (null list) list (...)) 简化为(and list (...)),因为如果(null list) 为真,那么list 必须为nil
  • 您的参数key 命名错误:key 函数是一个接受列表项并返回键进行比较的函数 (see the HyperSpec on sort)。您在这里拥有的(比较两个项目的函数)称为“谓词”。
  • 当您有(if ... (if ...)) 模式时,使用cond 通常会更清晰。
  • 没有文档字符串!

无论如何,解决所有这些小问题,并使用labels,结果如下:

(defun insertion-sort (list &optional (predicate #'<))
  "Return a sorted copy of list. Optional argument predicate must be a function
that takes two items and returns true if they are in order."
  (labels ((insert (item list)
                   (cond ((null list) (list item))
                         ((funcall predicate item (car list))
                          (cons item list))
                         (t (cons (car list) (insert item (cdr list)))))))
    (and list (insert (car list) (insertion-sort (cdr list) predicate)))))

请注意,现在insertinsertion-sort 的本地函数,我不必将predicate 参数传递给它,因为内部函数会从封闭上下文中获取绑定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    相关资源
    最近更新 更多