【问题标题】:Ambiguity in Hashmap?Hashmap 中的歧义?
【发布时间】:2019-11-08 13:51:26
【问题描述】:

我已经多次使用无序映射或哈希映射,但这是我第一次遇到这样的问题: 如果我运行这段代码:

string s  = "dvd";
for(int i = 0;i < s.size();i++){
        if(!map[s[i]]){
            cout<<s[i];
            map[s[i]] = i;
        }
    }

输出是

d v d

我的问题因为 d 已经在 map 中,所以为什么要再次打印代码。 另一个有趣的事情是,当我运行这段代码时

    string s = "dvd";

    unordered_map<char,int>map;
    for(auto i :s){
        if(!map[i]){
            cout<<i<<" ";
            map[i] = i;
        }    
    }

它给出了预期的输出

d v

我在这里错过了什么??

【问题讨论】:

  • i = 0 为假。
  • 所以值不能为 0 ?现在我尝试使用 map.find(s[i]) == map.end() 并且效果很好,知道为什么吗??
  • 因为这是检查地图是否包含给定键的正确方法。
  • 哦,我明白了,谢谢,

标签: c++ c++11 hashmap unordered-map


【解决方案1】:

实际上很容易解释如果您了解整数 0 转换为布尔值 false(任何非零值是 true)会发生什么,以及 ranged for loop work 是如何转换的。


如果我们从第一个循环开始:

for(int i = 0;i < s.size();i++){
    if(!map[s[i]]){
        cout<<s[i];
        map[s[i]] = i;
    }
}

这里的变量i代表字符串中字符的索引。索引将(按顺序)012

在第一次迭代中,'d' 不存在,因此map[s[i]] 将创建一个具有零值的元素,并返回零值。这使得条件为!0,这是正确的,因此您打印字符,然后将索引0 分配给map['d'](它已经 0)。

第二次迭代是相同的,但您将值 1 分配给 map['v']

然后进入第三次迭代,map['d'] 已经存在。 但是因为值是0 你的条件相信它不存在。

所以你的条件是有缺陷的。要检查密钥是否不存在,请使用 count

if (map.count(s[i]) == 0)

或者你可以使用find

if (map.find(s[i]) == map.end())

或者当 C++20 来的时候你可以使用contains

if (map.contains(s[i]))

然后是第二个循环:

for(auto i :s){
    if(!map[i]){
        cout<<i<<" ";
        map[i] = i;
    }    
}

这里i 不是索引,它是一个字符。因此,您分配给带有map[i] = i 的地图元素的值不会是012,而是编码字符值,对于ASCII 字符值100 和字符'd'118'v'

因此,在第一次迭代中,map[i] 将为零(就像之前一样),但随后您将 100 分配给该元素。

在第二次迭代中它是相同的,但您分配值 118

现在我们回到带有值100 的字母'd'。当您第二次检查map['d'] 时,该值不为零,并且您有!100,即false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-30
    • 2018-12-09
    相关资源
    最近更新 更多