我已经多次使用无序映射或哈希映射,但这是我第一次遇到这样的问题:如果我运行此代码:
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
我在这里想念的东西是什么?
如果您了解整数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。索引将是(按顺序)i
,0
和1
。
[第一次迭代时,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值将为0
。 1
代表2
。
因此,在第一次迭代中,100
将为零(就像以前一样,但是随后您将'd'
分配给该元素。
在第二次迭代中是相同的,但是您分配了值118
。
现在我们返回值为'v'
的字母map[i]
。当您第二次检查100
时,该值不为零,并且118
为'd'
。