我试图想出快速排序Common Lisp中的实现,这是我这么远:如何删除Lisp代码中的冗余?
(defun quick-sort (list)
(if (cdr list)
(let ((pivot (car list)))
(append (quick-sort (remove-if-not (lambda (n) (< n pivot)) list))
(remove-if-not (lambda (n) (= n pivot)) list)
(quick-sort (remove-if-not (lambda (n) (> n pivot)) list))))
list))
显然,它的工作原理,但我觉得有太多的重复在码。基本上,我们有三次:
(remove-if-not (lambda (n) (< n pivot)) list)
三个不同的调用的唯一方法是通过>
VS =
VS <
。
因此,我的问题是:我如何删除冗余,使代码更具可读性和更紧凑?
我当然可以提取的东西的功能,如:
(defun which (operator pivot list)
(remove-if-not (lambda (n) (funcall operator n pivot)) list))
(defun quick-sort (list)
(if (cdr list)
(let ((pivot (car list)))
(append (quick-sort (which #'< pivot list))
(which #'= pivot list)
(quick-sort (which #'> pivot list))))
list))
但不知何故,我真的不相信这是最好的办法。它仍然感到笨拙,必须一次又一次地交出pivot
和list
。
我也有想法,使用flet
,这使得该功能的实际身体更具可读性,但只有移动的复杂性到别的地方:
(defun quick-sort (list)
(if (cdr list)
(let ((pivot (car list)))
(flet ((left() (remove-if-not (lambda (n) (< n pivot)) list))
(middle() (remove-if-not (lambda (n) (= n pivot)) list))
(right() (remove-if-not (lambda (n) (> n pivot)) list)))
(append (quick-sort (left))
(middle)
(quick-sort (right)))))
list))
任何其他方法?
查看Kent Pitman在[Sheep Trick]中描述的Lisp中的quicksort实现(http://www.maclisp.info/pitmanual/funnies.html#sheep_trick)。 –