私は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)
3つの呼び出しが異なる唯一の方法は次のとおりです。基本的に、我々は3回を持っています。
私はこの冗長性を取り除き、コードをより読みやすくコンパクトにする方法を教えてください。もちろん
私は、次のような、関数に物事を抽出できます。
(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](http://www.maclisp.info/pitmanual/funnies.html#sheep_trick)で説明しているLispのquicksortの実装を見てみましょう。 –