44

STL マップをトラバースしたい。私はその鍵を使いたくありません。順序は気にしません。含まれているすべての要素にアクセスする方法を探すだけです。これどうやってするの?

4

6 に答える 6

72

はい、標準ライブラリをトラバースできますmap。これは、 をトラバースするために使用される基本的な方法mapであり、標準ライブラリ コレクションをトラバースするためのガイダンスとして機能します。

C++03/C++11:

#include <cstdlib>
#include <map>
#include <string>
using namespace std;

int main()
{
    typedef map<int,string> MyMap;
    MyMap my_map;
    // ... magic

    for( MyMap::const_iterator it = my_map.begin(); it != my_map.end(); ++it )
    {
      int key = it->first;
      string value = it->second;
    }
}

要素を変更する必要がある場合:

  • iteratorではなく使用しconst_iteratorます。
  • イテレータから値をコピーする代わりに、参照を取得して値を変更します。

    for( MyMap::iterator it = my_map.begin(); it != my_map.end(); ++it ) { int key = it->first; string& value = it->second; if( 値 == "foo" ) 値 = "バー"; }

これは通常、手動で標準ライブラリ コンテナーをトラバースする方法です。大きな違いは、 amapの型は要素自体ではなく*itaであるということですpair

C++11

C++11 コンパイラ (たとえば、--std=c++11MSVC を使用した最新の GCC) の利点がある場合は、他のオプションもあります。

まず、キーワードを使用しautoて、厄介な冗長性をすべて取り除くことができます。

#include <cstdlib>
#include <map>
#include <string>
using namespace std;

int main()
{
    map<int,string> my_map;
    // ... magic

    for( auto it = my_map.begin(); it != my_map.end(); ++it )
    {
      int key = it->first;
      string& value = it->second;
    }
}

次に、ラムダを使用することもできます。と組み合わせるとdecltype、よりクリーンなコードになる可能性があります (トレードオフはありますが)。

#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    map<int,string> my_map;
    // ... magic

    for_each(my_map.begin(), my_map.end(), [](decltype(*my_map.begin()) val)
    {
        string& value = val.second;
        int key = val.first;
    });
}

C++11 では、範囲ベースのループの概念も導入forされています。これは、他の言語と同様に認識される場合があります。ただし、一部のコンパイラはこれをまだ完全にはサポートしていません -- 特に MSVC.

#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;

int main()
{
    map<int,string> my_map;
    // ... magic

    for(auto val : my_map )
    {
        string& value = val.second;
        int key = val.first;
    }
}
于 2010-11-17T17:37:15.360 に答える
11

他の STL コンテナーと同様に、 メソッドbegin()end()メソッドは、マップの反復処理に使用できる反復子を返します。マップ イテレータを逆参照すると、std::pair<const Key, Value>.

于 2010-11-17T17:37:26.287 に答える
7

C++17

C++17以降、範囲ベースの for ループを構造化バインディングと一緒に使用して、マップを反復処理できます。結果として得られるコードは、たとえばマップのすべての要素を印刷するためのもので、短くて読みやすいです。

std::map<int, std::string> m{ {3, "a"}, {5, "b"}, {9, "c"} };

for (const auto &[k, v] : m)
    std::cout << "m[" << k << "] = " << v << std::endl;

出力:

m[3] = a
m[5] = b
m[9] = c

Coliru のコード

于 2019-03-27T07:46:14.853 に答える
5

他のSTLコンテナと同じ方法でSTLマップをトラバースできます。たとえば、イテレータを使用します。

for (std::map<key, value>::const_iterator
     i = myMap.begin(), end = myMap.end(); i != end; ++i)
{
    // *i is a key-value pair
}
于 2010-11-17T17:39:21.820 に答える