使用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。

Answers:


130

std::map::find将迭代器返回到找到的元素(end()如果找不到该元素,则返回)。只要map不是常量,就可以修改迭代器指向的元素:

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

1
@杰伊:是的,但是行为有所不同。有关map提供的各种功能,请参见文档map
James McNellis

3
我得到了error: assignment of member 'std::pair<char* const, char*>::second' in read-only object:(
汤姆·布里托

1
@jaykumarark我想是的,但是此解决方案的缺点是,地图必须第二次找到项目的位置(第一次是您对find方法的调用),这是操作log(N)的复杂性。这是相同操作的不必要的重复。
真相搜索者'16

51

我会使用operator []。

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(我不认为这是您的意图)。

好吧,我认为如果不想隐式插入一个元素,“查找”会更好。通过SIGSEGV取消“查找”和染色可能是更可取的。
木李

1
@GwangmuLee取消引用end()迭代器是未定义的行为,它不需要生成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;

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.