2017-12-08 12 views
1

非常に多くの場合、consingと追加のgcステップとリストとベクタを受け入れるジェネリックシーケンスに対するいくつかの関数の働きにより、リストはベクタに比べてパフォーマンスの面で不利になるという文が見つかる。ベクトルの交差関数はありますか?

しかし、intersectionのようないくつかの関数は2つのリストを期待しています。ベクトルの代替手段を提供するライブラリはありますか?

私はこのようなことから始めましたが、より成熟した解決策が必要だと感じました。

(defun vec-intersec (vec-1 vec-2 &aux (result (make-array 0 :adjustable t :fill-pointer 0))) 
    "A simple implementation of intersection for vectors instead of lists." 
    (loop :for v1 :across vec-1 
     :if (find v1 vec-2 :test #'equal) 
      :do (vector-push-extend v1 result)) 
    result) 
+4

操作は2次です。 パフォーマンスを意識している場合は、ハッシュテーブルを使用します。 それ以外の場合はリストに変換します。 – sds

+0

「ハッシュテーブルを使用する」の詳細を教えてください。ベクトルの代わりに、または 'find'を避けるための中間構造として? –

+0

HTメンバシップテストには一定のコストがありますので、それらを使用してセットを表すことは理にかなっています。 'Find'は線形なので、常に最適ではありません。 – sds

答えて

3

これは、あなたのコレクションのサイズと、それに何をしたいかによって異なります。

約20〜50個の要素の下では、ランダムアクセスの場合でもリストは完璧になることがよくあります。

ベクトルが既にある場合は、それらのうちの1つをソートして、ナイーブなリニアパターンではなくバイナリ検索ができるようにするのが最も便利です。それが十分でなく、あなたのコレクションが大きければ、要素をハッシュテーブル(キーとして適切な:test)に入れておくと、より高速な(償却された)ルックアップが得られます。

これはかなり遠いです。このような簡単な方法で解決できない問題がある場合は、より高度なデータ構造をサポートするFSetまたはCL-Containersを調べるとよいでしょう。

+0

また、ハッシュテーブルにそれらのうちの1つの要素(より短いもの、おそらく違いがある場合)をスラップして、ハッシュテーブルを使用して素早く存在を確認します。 – Vatine

+1

@Vatine:はい、それは第3段落の第2部の要点です。 – Svante

関連する問題