web-dev-qa-db-ja.com

STLマップをトラバース/反復するにはどうすればよいですか?

STLマップを横断したい。キーを使いたくありません。順序は気にせず、含まれるすべての要素にアクセスする方法を探しています。これどうやってするの?

34
atoMerz

はい、標準ライブラリ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;
    }
}

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

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

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

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

C++ 11

C++ 11コンパイラ(たとえば、--std=c++11またはMSVCを使用した最新の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;
    }
}
61
John Dibling

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

11
fredoverflow

STL map は、他のSTLコンテナと同じ方法でトラバースできます:イテレータを使用します。

for (std::map<key, value>::const_iterator
     i = myMap.begin(), end = myMap.end(); i != end; ++i)
{
    // *i is a key-value pair
}
5
vitaut

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のコード

1
honk

C++ 11以降の使用でforとともにautoを使用する

map<int,int> map_variable; //you can use any data type for keys, as well as value

for(auto &x:map_variable)
{ 
    cout<<x.first ;// gives the key
    cout<<x.second; //gives the value
}

forを使用するautoの新しい形式は、C++ 11で導入されました。

Pythonのようないくつかの高レベル言語のような機能を提供するには

そのようなタイプの反復の実装がすでにあった場合

追伸:マップ変数は値のソートを保持するため、反復するとキーがソート順に取得されます

0
Harsh Sharma

自動反復子を使用してマップを反復できます。

コードスニペット:

#include<bits/stdc++.h>
using namespace std;

int main()
{
      ios::sync_with_stdio(false);
      map<string, int> mp;

      mp["a"]=500;
      mp["b"]=200;
      mp["d"]=300;
      mp["c"]=400;

      for(auto it=mp.begin(); it != mp.end(); it++)
      {
         cout<<it->first <<" : "<<it->second<<endl;
      }
      return 0;
}
0
rashedcs