编辑给定键的无序映射中的值

Editing the value in an unordered map for a given key

以下是计算杂志字数的C++代码。如果该词的值不存在,我将尝试添加该词,如果存在,则将其递增。

unordered_map<string,int>hash;
vector<string> magazine(m);

for(int i = 0;i <m;i++)
{
   cin >> magazine[i];
   if(hash[magazine[i]]>0)
       hash[magazine[i]]++;
   else
    hash.emplace(magazine[i],1);
}

但是当我尝试输出时,所有杂志键的值都为 0。知道为什么吗?

您无意中在地图中创建了一个新元素:

if(hash[magazine[i]]>0)

map<>::operator[] 进行插入,值初始化(在你的情况下该值为零),然后returns 值的引用,都非常谨慎。

正如许多评论中正确建议的那样,最好的方法是:

hash[key]++ 

Read more.

如果键不存在,

if(hash[magazine[i]]>0) 创建 new 项。

你真正想要的是:

if(hash.find(magazine[i])!=hash.end())

如@juanchopanza 所述,您不需要分支。 std::unordered_map::operator [] 可以这样处理:

hash[magazine[i]]++;

您的版本不起作用,因为此 if(hash[magazine[i]]>0) 将向 hash 插入一个元素(如果该元素不存在),此新元素的映射值为 0¹ .这意味着 hash.emplace(magazine[i],1); 在这里毫无意义,因为现在 总是 magazine[i] 处的一个元素。因为它的值将是 0,所以您的 hash[magazine[i]]++; 永远不会 运行,因为 if 永远不会是 true。给你留下 i 个元素的映射,所有元素的值都为 0.

operator[] returns 对映射值的引用(如果有),如果没有,则插入一个,然后 returns 该引用¹。

这意味着您可以分解出 if 并将其更改为:

for(int i = 0;i <m;i++)
{
   cin >> magazine[i];
   ++hash[magazine[i]];
}

这基本上意味着:“获取对键 magazine[i] 的映射值的引用,如果找到 none,插入一个并给我那个。增加这个引用."

¹: 如果发生插入,则元素被值初始化。因为您的映射值类型是 int 这将导致插入后映射值是 0