我检查该元素是否已经在哈希表中并且更改了输出 有人可以解释一下原因吗?
#include <iostream>
#include <unordered_map>
using namespace std;
int main(int argc, char *argv[]){
char c = 'a';
unordered_map<char,int> myhashmap;
cout << myhashmap[c] << endl; // <<--- This line
myhashmap.insert({c,1});
cout << myhashmap[c] << endl;
cout << endl;
}
输出
0
0
但如果删除标记的行,则输出为
1
起初我想,可能是因为检查一个键可能会插入值为零,当我实际插入它时,这将是一个碰撞。所以我检查了unordered_map如何处理碰撞。显然它把它放在桶里。所以我接着这样做,看看我的怀疑是否正确。我所做的就是打印所有水桶和它们的尺寸。
#include <iostream>
#include <unordered_map>
using namespace std;
int main(int argc, char *argv[]){
char c = 'a';
unordered_map<char,int> myhashmap;
for (unsigned i=0; i<myhashmap.bucket_count(); ++i) {
std::cout << "bucket #" << i << " has " << myhashmap.bucket_size(i) << " elements.\n";
}
cout << endl;
cout << myhashmap[c] << endl; // Line 1 - check if the key is present
cout << endl;
for (unsigned i=0; i<myhashmap.bucket_count(); ++i) {
std::cout << "bucket #" << i << " has " << myhashmap.bucket_size(i) << " elements.\n";
}
cout << endl;
myhashmap.insert({c,1}); // Line 2 - Insert into hashTable
cout << myhashmap[c] << endl;
cout << endl;
for (unsigned i=0; i<myhashmap.bucket_count(); ++i) {
std::cout << "bucket #" << i << " has " << myhashmap.bucket_size(i) << " elements.\n";
}
}
唉,我的假设是错误的。最初所有桶的大小都为零。当我检查密钥(第1行)时,其中一个桶的大小变为1.但即使在插入(第2行)之后,桶的大小仍为1,但输出为0而不是1.我必须误解一些非常基本的哈希表。如果有人能解释我做错了什么,我将不胜感激
由于
答案 0 :(得分:2)
起初我想,可能是因为检查密钥可能会将其插入零值
这正是发生的事情。您没有正确检查它。以下是执行myhashmap[c]
时如何查看插入的内容:
char c = 'a';
unordered_map<char,int> myhashmap;
cout << "Size before: " << myhashmap.size() << endl;
cout << myhashmap[c] << endl;
cout << "Size after: " << myhashmap.size() << endl;\
auto iter = myhashmap.find(c);
cout << "iter is valid: " << (iter != myhashmap.end()) << endl;
cout << "Key is " << iter->first << endl;
cout << "Value is " << iter->second << endl;
该程序产生以下输出:
Size before: 0
0
Size after: 1
iter is valid: 1
Key is a
Value is 0
答案 1 :(得分:1)
首先,让我们看看std::unordered_map::operator[]:
返回对映射到等效于key的键的值的引用,如果此类键尚不存在则执行插入。 如果执行插入,则映射值是值初始化的(默认为类类型构造,否则为零初始化),并返回对它的引用。
因此,在您的第一行{'a',0}
中插入了地图。现在打电话给std::unordered_map::insert:
将元素插入容器中,如果容器尚未包含具有等效键的元素。
(强调我的。)因此,如果您在operator[](c)
之前致电insert({c,1})
,则对insert
的调用无效,否则会插入{c,1}
。