連続した値のセットを含まないデータ構造は、スパースまたは圧縮データ構造と呼ばれます。これはあなたが探しているものだと思われます。
この場合、スパースベクトルが必要です。ブーストに実装されているものが1つあります。link text
通常、メモリを節約するために疎構造が使用されます。問題の説明からは、実際にメモリの使用を気にする必要はなく、まだ存在しない要素に対処すること(自動サイズ変更のコンテナを使用すること)が可能です。この場合、外部依存関係のない単純な解は次のようになります。
ベクトルを保持し、すべてのベクトルメソッドをそれに転送するテンプレートクラスを作成します。インデックスが範囲外の場合は、演算子[]を変更してベクトルのサイズを変更します。
// A vector that resizes on dereference if the index is out of bounds.
template<typename T>
struct resize_vector
{
typedef typename std::vector<T>::size_type size_type;
// ... Repeat for iterator/value_type typedefs etc
size_type size() const { return m_impl.size() }
// ... Repeat for all other vector methods you want
value_type& operator[](size_type i)
{
if (i >= size())
resize(i + 1); // Resize
return m_impl[i];
}
// You may want a const overload of operator[] that throws
// instead of resizing (or make m_impl mutable, but thats ugly).
private:
std::vector<T> m_impl;
};
他の回答に記載されているように、ベクトルのサイズを変更すると要素はクリアされません。代わりに、新しい要素がサイズ変更によって追加されると、デフォルトのコンストラクタが呼び出されます。したがって、このクラスを使用する際には、operator[]
がデフォルトの構築オブジェクト参照を返す可能性があることを知る必要があります。したがって、<T>
のデフォルトのコンストラクタは、オブジェクトをこの目的に合った適切な値に設定する必要があります。たとえば、要素に以前に値が割り当てられているかどうかを知る必要がある場合は、センチネル値を使用できます。
std::map<size_t, T>
を使用することの提案は、余分なメモリの使用、不連続な要素記憶域、およびO(1)ではなくO(logN)ルックアップを考慮した場合のメリットがあります。これは、疎な表現か自動サイズ変更のどちらを必要とするかにかかっています。うまくいけば、この答えは両方をカバーします。
出典
2009-05-30 19:16:47
Jon
マップを使用する方がよいでしょうか? – Silfverstrom
あなたの仕事にベクトルを選んだ理由は何ですか?すべての要素が連続したメモリに存在する必要がありますか?あなたは配列を必要とするC APIとインターフェースしていますか? –
私はあなたが正しいと思う地図はこのタスクの方が適しています。ありがとう。 – Saobi