您的位置:首页 > 编程语言 > C语言/C++

C++ unordered_map

2016-07-27 09:08 477 查看

unordered_map的定义

template < class Key,
class T,
class Hash = hash<Key>,
class Pred = equal_to<Key>,
class Alloc = allocator< pair<const Key,T> >> class unordered_map;


模版参数说明:

Key

主键的类型。

在类模板内部,使用其别名为 key_type 的成员类型。

T

被映射的值的类型。

在类模板内部,使用其别名为 mapped_type 的成员类型。

Hash

一元谓词,以一个 Key 类型的对象为参数,返回一个基于该对象的 size_t 类型的唯一值。可以是函数指针(Function pointer)类型或函数对象(Function object)类型。在类模板内部,使用其别名为 hasher 的成员类型。

Pred

二元谓词,以两个 Key 类型的对象为参数,返回一个 bool 值,如果第一个参数等价于第二个参数,该 bool 值为 true,否则为 false。默认为 std::equal_to.可以是函数指针类型(Function pointer)类型或函数对象(Function object)类型.在类模板内部,使用其别名为 key_equal 的成员类型。

Alloc

容器内部用来管理内存分配及释放的内存分配器的类型。这个参数是可选的,它的默认值是 std::allocator,这个是一个最简单的非值依赖的(Value-independent)内存分配器。在类模板内部,使用其别名为 allocator_type 的成员类型。

特点

unordered_map是一个关联容器,存储key,value.其中元素并没有特别的次序关系

特点:

1. 关联容器中的元素是通过主键(Key)而不是它们在容器中的绝对位置来引用的。

2. 无序(Unordered)无序容器通过 hash 表来组织它们的元素,允许通过主键快速地访问元素。

3. 映射(Map)每个元素为一个值(Mapped value)绑定一个键(Key):以主键来标志主要内容等于被映射值的元素。

4. 键唯一(Unique keys)容器中不存在两个元素有相同的主键。

5. 能够感知内存分配器的(Allocator-aware)容器使用一个内存分配器对象来动态地处理它的存储需求。

在 unordered_map 内部,元素不会按任何顺序排序,而是通过主键的 hash 值将元素分组放置到

各个槽(Bucket,也可译成“桶”)中,这样就能通过主键快速地访问各个对应的元素

(平均耗时为一个常量,即时间复杂度为 O(1))。

成员函数

=================迭代器=========================

begin 返回指向容器起始位置的迭代器(iterator)

end 返回指向容器末尾位置的迭代器

cbegin 返回指向容器起始位置的常迭代器(const_iterator)

cend 返回指向容器末尾位置的常迭代器

=================Capacity================

size 返回有效元素个数

max_size 返回 unordered_map 支持的最大元素个数

empty 判断是否为空

=================元素访问=================

operator[] 访问元素

at 访问元素

=================元素修改=================

insert 插入元素

erase 删除元素

swap 交换内容

clear 清空内容

emplace 构造及插入一个元素

emplace_hint 按提示构造及插入一个元素

================操作=========================

find 通过给定主键查找元素

count 返回匹配给定主键的元素的个数

equal_range 返回值匹配给定搜索值的元素组成的范围

================Buckets======================

bucket_count 返回槽(Bucket)数

max_bucket_count 返回最大槽数

bucket_size 返回槽大小

bucket 返回元素所在槽的序号

load_factor 返回载入因子,即一个元素槽(Bucket)的最大元素数

max_load_factor 返回或设置最大载入因子

rehash 设置槽数

reserve 请求改变容器容量

测试

#include <unordered_map>
#include <iostream>
#include <string>

using namespace std;

void PrintIntDoubleUnOrderedMap(unordered_map<int, double>& m, char* pre)
{
unordered_map<int, double>::iterator iter;
cout << pre;
for (iter = m.begin(); iter != m.end(); ++iter)
cout << "(" << iter->first << ", " << iter->second << ")" << " ";
cout << endl;
}

void UnOrderedMapExp1()
{
unordered_map<int, double> m;
//没有key,就自动创建
m[0] = 1.11;
//普通插入,使用类型转换
m.insert(unordered_map<int, double>::value_type(1, 2.22));
//带暗示的插入,pair<int, double>就相当于上面的unordered_map<int ,double>
m.insert(m.end(), pair<int, double>(2, 3.33));
PrintIntDoubleUnOrderedMap(m, "插入元素之前的m:");

//插入一个范围
unordered_map<int, double> m2;
m2.insert(unordered_map<int, double>::value_type(3, 4.44));
m2.insert(unordered_map<int, double>::value_type(4, 5.44));
m2.insert(unordered_map<int, double>::value_type(5, 6.44));
m.insert(m2.begin(), m2.end());

m.emplace(6, 5.55);
m.emplace_hint(m.end(), 7, 3.09);
m.at(5) = 3.333333;

PrintIntDoubleUnOrderedMap(m, "插入元素之后m:");

unordered_map<int, double>::iterator iter;
iter = m.find(4);
if (iter != m.end())
{
cout << "m.find(4): ";
cout << "(" << iter->first << ", " << iter->second << ")" << endl;
}

if (iter != m.end())
{
m.erase(iter);
}
PrintIntDoubleUnOrderedMap(m, "删除主键为4的元素之后m:");

//遍历删除
for (iter = m.begin(); iter != m.end(); ++iter)
{
if (iter->first == 2)
{
m.erase(iter);
break;
}
}

//内部数据
cout << "bucket_count:" << m.bucket_count() << endl;
cout << "max_bucket_count:" << m.max_bucket_count() << endl;
cout << "bucket_size:" << m.bucket_size(0) << endl;
std::cout << "load_factor:" << m.load_factor() << std::endl;
std::cout << "max_load_factor:" << m.max_load_factor() << std::endl;
PrintIntDoubleUnOrderedMap(m, "删除主键为2的元素后的foo1:");
m.clear();
PrintIntDoubleUnOrderedMap(m, "清空后的foo1:");
}

int main()
{
UnOrderedMapExp1();

return 0;
}


以类作为key,value

只是用STL提供的基本类型int, char, long等和stringz作为key,value,STL提供了哈希函数和比较函数。但是用自己定义的类时,需要自己定义哈希函数和比较函数

//hash函数
template <typename T>
class hash
{
public:
size_t operator()(const T& o) const { return 0; }
};

//compare函数
template <typename T>
class equal_to
{
public:
bool operator()(const T& a, const T& b) const { return a == b; }
};


下面以一个学号姓名为例子来实现

#include <unordered_map>
#include <iostream>
#include <string>

using namespace std;

//自己设计类,作为key和value

//学号
class Number
{
string str;
public:
Number() { }
Number(string s) { str = s; }

const string& get() const
{
return str;
}
};

//姓名
class Name
{
string str;
public:
Name() {}
Name(string s) { str = s; }

const string& get() const
{
return str;
}
};

//哈希函数对象实现
// 必须为const
class MyHash
{
public:

size_t operator()(const Number& num) const
{
hash<string> sh;        //使用STL中hash<string>
return sh(num.get());
}
};

//实现equal_to对象
//必须为const
class MyEqualTo {
public:

bool operator()(const Number& n1, const Number& n2) const
{
return n1.get() == n2.get();
}
};

int main()
{
unordered_map<Number, Name, MyHash, MyEqualTo> map;
map.emplace(Number("1000"), Name("A"));
map.emplace(Number("1001"), Name("G"));
map.emplace(Number("1002"), Name("E"));
map.emplace(Number("1003"), Name("D"));

unordered_map<Number, Name, MyHash, MyEqualTo>::iterator iter;
Number num("1001");
iter = map.find(num);

if (iter != map.end())
cout << "Number: " << iter->first.get() << "," << "Name: " << iter->second.get() << endl;

else
cout << "Not found!" << endl;

return 0;
}


参考:http://www.cplusplus.com/reference/unordered_map/unordered_map/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: