2009-11-27 44 views
6

C++のstd :: mapには.resize()メンバ関数がないので、どのようにして最大n個の要素を持つstd :: mapを得ることができるのだろうと思います。std :: mapの最初のn要素を取得する方法

明白な解決策は、0からnまでのループを作成し、std :: erase()の最初のパラメータとしてn番目のイテレータを使用することです。

ループが必要ない(少なくとも私のユーザーコードではない)ソリューションがあるのだろうかと思っていましたが、もっと "STLのやり方"です。

+1

Hmm ..イテレーターループを使用していると言うと、STLの方法はありますか? – schnaader

+2

'std :: erase'はありません。 'std :: map :: erase()'を使用してください –

答えて

13

これにはstd::advance(iter, numberofsteps)を使用できます。

+0

+1 - これは分かりませんでした。 – schnaader

0

マップのサイズを変更したいのはなぜですか?マップ内

要素は任意の順序で格納されていません -

編集最初の「n」は本当に何を意味するものではありません。
興味深いことにはstd ::マップが注文を持っていない、わからないどのように便利このコンセプトは、
エントリはキーと同じソート順になっていますか?
それはどういう意味ですか? SSNによってキー入力された名前があれば、名前はSSNの数字順に格納されますか?

+0

キーで順序付けされた要素はありませんか? –

+0

あなたの考え方ではなく、要素が何らかの順序で記憶にあります。キーをインデックスに変換するハッシュアルゴリズムがあります。 しかし、key1とkey2の要素は必ずしも隣り合っている必要はありません。 –

+3

@mgb いいえ、それはハッシュテーブルです。 std :: mapはバイナリ検索ツリーです(通常は赤黒のツリーを指定します)。したがって、std :: mapの要素は、簡単かつ高速に反復処理する方法で格納されます。 – Tim

1

std :: mapはリストではありません。 「最初のn」要素はありません。

BTW:コンテナが変更された場合、イテレータは無効になります。

本当に小さいマップが必要な場合は、それを繰り返して、n番目までのすべての要素を新しいマップに追加することができます。

+3

さて、要素はキーでソートされていますか? – Nailer

+0

@Nailer:ニース、私はそれを知らなかった。このリンクは次のことを確認しています:http://www.cplusplus.com/reference/stl/map/ – ya23

+1

はい、そうです。しかし、地図は「ノードの(バランスのとれた)ツリーとして実装される可能性が最も高い」(「The C++ programming language」、Bjarne Stroustrupの引用)であり、リストではない。だからmymap [n]は意味をなさない。 – EricSchaefer

3

std :: list、std :: map、boost :: multi_indexなど、ほぼすべてのコンテナのためのユニバーサルソリューションです。地図のサイズのみを確認する必要があります。

template<class It> 
It myadvance(It it, size_t n) { 
    std::advance(it, n); 
    return it; 
} 

template<class Cont> 
void resize_container(Cont & cont, size_t n) { 
    cont.erase(myadvance(cont.begin(), std::min(n, cont.size())), 
       cont.end()); 
} 
+0

これはvoid std :: advance()なので、これはコンパイルされませんでした。 – Norbert

+0

右。直した。 –

+0

+1ですが、これをリリースするために整理していたのであれば、 'resize_container'がどのコンセプトで動作しているか心に留めておく必要があります。関数とテンプレートのパラメータ名は、任意のコンテナを示します。関数のパラメータ名は任意のマップを示唆します。私が書いたように、実際にはSequenceまたはAssociative Containerで動作すると思いますが、残念なことにそのドメインはC++分類のポリフィリックグループです。 –

1

正しい方法はstd :: advanceを使用することです。しかし、ここでは「マップ上でサイズ変更を使用する」ことを可能にする面白い(遅い)方法があります。より一般的には、この種のトリックはベクトル上で動作する他のものには使用できますが、マップ上では使用できません。

map<K,V> m; //your map 
vector< pair<K,V> > v(m.begin(), m.end()); 
v.resize(n); 
m = map<K,V>(v.begin(),v.end()); 
関連する問題