【问题标题】:Editing the value in an unordered map for a given key编辑给定键的无序映射中的值
【发布时间】:2017-03-05 21:15:25
【问题描述】:

以下是获取杂志中字数的 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]]&gt;0) 你是做什么的?
  • 阅读 Eric Lippert 的 How to debug small programs。您的调试器是回答这个问题的正确工具。

标签: c++ unordered-map emplace


【解决方案1】:

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

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

这意味着您可以将if 分解为:

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

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

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

【讨论】:

  • 请在答案中添加新创建的值是默认初始化的,这意味着它对于数字类型的值为 0。
  • 这行得通,但你还没有解释为什么以前的版本不起作用(这是 OP 实际要求的)。
  • @Leon 它是 value 初始化的,这意味着它对于数字类型的值为 0。数值类型的默认初始化不做任何事情。
【解决方案2】:

if(hash[magazine[i]]&gt;0) 如果密钥不存在,则创建 new 项。

你真正想要的是:

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

正如@juanchopanza 提到的,您不需要分支。 std::unordered_map::operator [] 可以这样处理:

hash[magazine[i]]++;

【讨论】:

  • 不,他们不需要任何条件。只需hash[magazine[i]]++;
  • 或者完全删除if,然后使用hash[magazine[i]]++;。如有必要,该元素将使用值 0 创建,然后递增。这 用于索引到地图的用例,如果它不存在则创建一个元素 - 我仍然认为这是错误的决定。
  • @juanchopanza 您的意思是它默认为 0 并且 ++ 负责使其成为 1 ?即便如此,OP 需要澄清正在发生的事情以及 IMO 的确切替代方案是什么
  • 并非如此,hash[magazine[i]]++; 始终是这里的答案。
  • @juanchopanza @Martin @GillBates hash[magazine[i]]++; 没有回答OP 提出的问题。添加到答案中(可能)是一个有用的评论。
【解决方案3】:

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

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

map&lt;&gt;::operator[] 进行插入、值初始化(在您的情况下该值为零),然后返回值的引用,都非常谨慎。

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

hash[key]++ 

Read more.

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 2020-03-11
    • 1970-01-01
    • 2017-09-20
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多