Hashmap中的歧义?

问题描述 投票:0回答:1

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

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

我在这里想念的东西是什么?

c++ c++11 hashmap unordered-map
1个回答
0
投票

如果您了解整数0转换为布尔值false(并且任何非零为true的方式,以及ranged for loop work的方式,那么这实际上很容易解释。


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

for

这里变量for(int i = 0;i < s.size();i++){ if(!map[s[i]]){ cout<<s[i]; map[s[i]] = i; } } 表示字符串中字符的index。索引将是(按顺序)i01

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

第二次迭代是相同的,但是您将值0分配给1

然后您进入第三次迭代,其中map['v']已存在。 但是由于该值为map['d'],因此您的条件认为该值不存在。

所以您的情况有缺陷。要检查密钥是否不存在,请使用0

count

或者您可以使用count

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

或者当C ++ 20出现时,您可以使用find

find

然后第二个循环:

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

这里contains不是索引,它是字符。因此,您使用contains分配给地图元素的值将不是if (map.contains(s[i])) for(auto i :s){ if(!map[i]){ cout<<i<<" "; map[i] = i; } } i,而是编码后的字符值,对于字符map[i] = i和ASCII,ASCII值将为01代表2

因此,在第一次迭代中,100将为零(就像以前一样,但是随后您将'd'分配给该元素。

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

现在我们返回值为'v'的字母map[i]。当您第二次检查100时,该值不为零,并且118'd'

© www.soinside.com 2019 - 2024. All rights reserved.