はい、対数の複雑さにはマルチセットを使用する必要があります。しかし、set/map イテレータは RandomAccess ではなく Bidirectional であるため、距離の計算が問題です。 std::distance には O(n) の複雑さがあります。
multiset<int> my_set;
...
auto it = my_map.lower_bound(3);
size_t count_inserted = distance(it, my_set.end()) // this is definitely O(n)
my_map.insert(make_pair(3);
あなたの複雑さの問題は複雑です。完全な分析は次のとおりです。
挿入ごとに O(log(n)) の複雑さが必要な場合は、セットとして並べ替えられた構造が必要です。新しいアイテムを追加するときに構造がアイテムを再割り当てまたは移動しないようにする場合、挿入ポイントの距離の計算は O(n) になります。事前に挿入サイズがわかっている場合は、ソートされたコンテナーでの対数挿入時間は必要ありません。すべてのアイテムを挿入して並べ替えることができます。これは、セット内の n * O(log(n)) 挿入と同じ O(n.log(n)) です。唯一の代替手段は、加重 RB ツリーのような専用コンテナーを使用することです。問題によっては、これが解決策になることもあれば、やり過ぎになることもあります。
- とを使用する
multiset
とdistance
、挿入時に O(n.log(n)) (はい、n 個の挿入 * それぞれの挿入時間の log(n))、距離計算で O(nn) になりますが、距離の計算は非常に高速です。
- 挿入されたデータのサイズ (n) が事前にわかっている場合: ベクトルを使用し、塗りつぶし、並べ替え、距離を返すと、O(n.log(n)) になり、コーディングが簡単になります。
- 事前に n がわからない場合、n は巨大である可能性が高く、各アイテムはメモリが重いため、 O(n.log(n)) 再割り当てを行うことはできません。再エンコードまたは一部を再利用する時間があります。非標準コードの場合、これらの複雑さの期待を満たす必要があり、専用のコンテナーを使用する必要があります。データベースの使用も検討してください。これをメモリに保持する際に問題が発生する可能性があります。