Coding style 如何消除Lisp代码中的冗余?
我曾尝试在Common Lisp中实现快速排序,到目前为止,我得到的是:Coding style 如何消除Lisp代码中的冗余?,coding-style,lisp,common-lisp,Coding Style,Lisp,Common Lisp,我曾尝试在Common 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)
(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))
但不知何故,我并不确信这是否是最好的方法。要一次又一次地交出透视图
和列表
,仍然感觉很笨拙
我还想到了使用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))
(取消快速排序(列表)
(如果(cdr列表)
(让((枢轴(车辆列表)))
(flet((左()(如果不是则删除)(lambda(n)(n pivot))列表),则删除)
(附加(快速排序(左))
(中)
(快速排序(右‘‘‘))
(列表)
还有其他方法吗?如果将其作为本地函数编写,则不必传递额外的参数,因为它们在作用域中
(defun quick-sort (list)
(if (rest list)
(let ((pivot (first list)))
(flet ((filter (operator)
(remove-if-not (lambda (n) (funcall operator n pivot)) list)))
(append (quick-sort (filter #'<))
(filter #'=)
(quick-sort (filter #'>)))))
list))
此版本基于Sedgewick的代码。是的,当然:-)!(有时解决方案很简单,但你看不到它…谢谢你指出这一点:-)PS:这里的
append
很好,还是我应该使用ncoc
?最新版本的快速排序
可能是最有效的,但是很难理解…@mobiuseng:我让它更容易理解。看看Kent Pitman在中描述的Lisp中的快速排序实现。
(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))
(defun quick-sort (list)
(if (rest list)
(let ((pivot (first list)))
(flet ((filter (operator)
(remove-if-not (lambda (n) (funcall operator n pivot)) list)))
(append (quick-sort (filter #'<))
(filter #'=)
(quick-sort (filter #'>)))))
list))
(defun quick-sort (list &aux (pivot (first list)))
(flet ((filter (operator)
(remove-if-not (lambda (n) (funcall operator n pivot)) list)))
(and list
(nconc (quick-sort (filter #'<))
(filter #'=)
(quick-sort (filter #'>))))))
(defun partition (list pivot)
(loop for e in list
when (< e pivot) collect e into smaller else
when (> e pivot) collect e into larger else
when (= e pivot) collect e into same
finally (return (values smaller same larger))))
(defun quick-sort (list)
(if (rest list)
(multiple-value-bind (smaller same larger)
(partition list (first list))
(append (quick-sort smaller) same (quick-sort larger)))
list))
(defun partition (array left right &aux (i (1- left))
(j right)
(v (aref array right)))
(loop do (loop do (incf i) until (>= (aref array i) v))
(loop do (decf j) until (or (zerop j)
(<= (aref array j) v)))
(rotatef (aref array i) (aref array j))
until (<= j i))
(rotatef (aref array j) (aref array i) (aref array right))
i)
(defun quicksort (array &optional (left 0) (right (1- (length array))))
(if (> right left)
(let ((i (partition array left right)))
(quicksort array left (1- i))
(quicksort array (1+ i) right))
array))