我試圖想出快速排序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)。 –