私は Common Lisp でマージソートの一般的な実装を持っています: 私は分割関数とマージ関数の異なる実装を持っており、分割関数とマージ関数の組み合わせごとにマージソート関数を構築したいと考えています。
- どの分割関数も文字列のリストを入力として取り、2 つのリスト (元のリストの 2 つの半分) のリストを返します。
- どのマージ関数も、2 つの並べ替えられたリストを入力として取り、並べ替えられたマージされたリストを返します。
各マージ ソート関数は、次の関数を呼び出すことによって作成されます。
(defun make-merge-sort-function (split-function merge-function)
(defun merge-sort (lst)
(if (or (null lst) (null (cdr lst)))
lst
(let ((s (funcall split-function lst)))
(funcall merge-function (merge-sort (car s)) (merge-sort (cadr s))))))
(lambda (lst)
(merge-sort lst)))
名前をプライベートに保ち、名前空間を台無しにしないように、merge-sort
内部で定義しました。make-merge-sort-function
私のコードは、いくつかの Common Lisp 実装 (Steel Bank Common Lisp など) で動作します。
- すべてのテスト実行の出力が適切にソートされ、
- 結果のマージソート関数ごとに実行時間が異なり、異なる分割/マージの組み合わせが使用されたことを示しています。
したがって、私のコードは正しいと思います。
ただし、Allegro Common Lisp でプログラムを実行すると、次の警告が表示されます。
Warning: MERGE-SORT is defined more than once as `operator' in file foo.lisp.
whereは呼び出されるfoo.lisp
ファイルです。したがって、プログラムは正常に動作しますが、最初の呼び出しの後にmake-merge-sort-function
呼び出しごとにこの警告が出力されます。関数をグローバルmake-merge-sort-function
にすると (2 つの引数とが追加されます)、警告は消えます。merge-sort
split-function
merge-function
Allegro Common Lisp では、この警告の意味に関する兆候は見つかりませんでした。私が試した他の実装 (ABCL、CMUCL、CCL、CLISP、SBCL) では、警告は表示されません。内部関数 (クロージャー) の新しいインスタンスが複数回定義されても問題ないと思いますが、これが問題になる理由がわかりません。何か案は?