findメソッドを使用した後にstd :: mapを更新する方法は?


90

メソッドstd::mapを使用した後にキーの値を更新するにはどうすればよいfindですか?

私はこのようなマップとイテレータ宣言を持っています:

map <char, int> m1;
map <char, int>::iterator m1_it;
typedef pair <char, int> count_pair;

マップを使用して、文字の出現回数を保存しています。

Visual C ++ 2010を使用しています。

回答:


130

std::map::find見つかった要素(またはend()要素が見つからなかった場合)へのイテレータを返します。mapがconstでない限り、イテレータが指す要素を変更できます。

std::map<char, int> m;
m.insert(std::make_pair('c', 0));  // c is for cookie

std::map<char, int>::iterator it = m.find('c'); 
if (it != m.end())
    it->second = 42;

2
ありがとう。[]演算子を使用することもできますか?
jaykumarark 2010

1
@ジェイ:はい、でも振る舞いは違います。によって提供されるさまざまな機能については、mapドキュメントを参照してくださいmap
James McNellis 2010

3
私が得たerror: assignment of member 'std::pair<char* const, char*>::second' in read-only object:(
トム・ブリトに

1
@jaykumararkはいと思いますが、このソリューションの欠点は、マップがアイテムの場所を2回目に検索する必要があることです(1回目はfindメソッドの呼び出しです)。これはlog(N)の複雑さを伴う操作です。同じ操作の不必要な重複です。
Truthseeker 2016年

51

演算子[]を使用します。

map <char, int> m1;

m1['G'] ++;  // If the element 'G' does not exist then it is created and 
             // initialized to zero. A reference to the internal value
             // is returned. so that the ++ operator can be applied.

// If 'G' did not exist it now exist and is 1.
// If 'G' had a value of 'n' it now has a value of 'n+1'

したがって、この手法を使用すると、ストリームからすべての文字を読み取り、それらを数えることが非常に簡単になります。

map <char, int>                m1;
std::ifstream                  file("Plop");
std::istreambuf_iterator<char> end;

for(std::istreambuf_iterator<char> loop(file); loop != end; ++loop)
{
    ++m1[*loop]; // prefer prefix increment out of habbit
}

3
あなたの答えは実際の質問に最適です-悲しいことに、質問者はこれを明白な方法で尋ねる(したがって受け入れる)ことができませんでした。そのため、この事実について短い説明をする方がよいと思います。非常に速く「読む」人は、使用した[]後に使用することを提案していると信じているかもしれfindません(これがあなたの意図ではなかったと思います)。
オオカミ

暗黙のうちに要素を挿入したくない場合は、「find」の方が適していると思います。'find'を逆参照し、SIGSEGVで死ぬことが好ましい場合があります。
光武李

1
@GwangmuLeeend()イテレータの逆参照は未定義の動作であり、生成する必要はありませんSIGSEGV(私の経験では、生成する可能性は低いです)。
マーティンヨーク

5

std::map::atメンバー関数を使用できます。これは、キーkで識別される要素のマップされた値への参照を返します。

std::map<char,int> mymap = {
                               { 'a', 0 },
                               { 'b', 0 },
                           };

  mymap.at('a') = 10;
  mymap.at('b') = 20;

1

キーがすでにわかっている場合は、を使用してそのキーの値を直接更新できます。 m[key] = new_value

これが役立つかもしれないサンプルコードです:

map<int, int> m;

for(int i=0; i<5; i++)
    m[i] = i;

for(auto it=m.begin(); it!=m.end(); it++)
    cout<<it->second<<" ";
//Output: 0 1 2 3 4

m[4] = 7;  //updating value at key 4 here

cout<<"\n"; //Change line

for(auto it=m.begin(); it!=m.end(); it++)
    cout<<it->second<<" ";
// Output: 0 1 2 3 7    

0

あなたもこのようにすることができます-

 std::map<char, int>::iterator it = m.find('c'); 
 if (it != m.end())
 (*it).second = 42;

0

次のように値を更新できます

   auto itr = m.find('ch'); 
     if (itr != m.end()){
           (*itr).second = 98;
     }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.