頻繁に変化する N 個の異なる数値の配列があります。変更するたびに、2 つ以上の数値が等しくなる可能性がありますが、それは望ましくありません。数値 N は、可能な最大整数と同じ大きさにすることができます。変更が頻繁に発生することを知っているので、各変更後に各数値を残りの各数値と比較したくありません。
配列に少なくとも 2 つの等しい数値があるかどうかをすばやく確認するにはどうすればよいですか?
頻繁に変化する N 個の異なる数値の配列があります。変更するたびに、2 つ以上の数値が等しくなる可能性がありますが、それは望ましくありません。数値 N は、可能な最大整数と同じ大きさにすることができます。変更が頻繁に発生することを知っているので、各変更後に各数値を残りの各数値と比較したくありません。
配列に少なくとも 2 つの等しい数値があるかどうかをすばやく確認するにはどうすればよいですか?
前者はO(log(n))
平均して操作を提供し、後者は - O(1)
; 実際の結果は、使用しているストリームの種類によって異なります (数字はランダムですか? 増加していますか? 奇妙で非自明なパターンに従っていますか?)
BST を選択する場合は、バランスを保つ必要があることを忘れないでください。
(defparameter *my-data-array* (make-array 100000))
;; fill *my-data-array*
(defparameter *my-data-table*
(let ((ht (make-hash-table)))
(loop for v across *my-data-array*
do (incf (gethash v *my-data-table* 0)))
ht))
(defun modify-data-array (pos new-value)
(let* ((old-value (aref *my-data-array* pos))
(old-count (decf (gethash old-value *my-data-table*)))
(new-count (incf (gethash new-value *my-data-table* 0))))
(setf (aref *my-data-array* pos) new-value)
(case old-count
(0 ; old-value is now not in the array
...)
(1 ; old-value is now unique
...)
(t ; old-value is still not unique
...))
(case new-count
(1 ; new-value was not in the array before
...)
(2 ; new-value was unique before, but not anymore
...)
(t ; new-value was not unique
...))))
バリアントとして、Bloom filterを使用できます。指定された番号がすでに追加されているかどうかをテストできます。ただし、誤検知エラーが発生する可能性があります。一方、ブルームフィルターはスペース効率が高く高速であり、配列を保持できます。ブルーム フィルター アルゴリズムは、反復する数値をめったに使用しない場合に役立ちます。そうでない場合は、線形時間で数値を頻繁に再テストする必要があります。