std::unordered_map(C++11)
unordered_map是一个关联容器,内部采用的是hash表结构,拥有快速检索的功能。
特性
关联性:通过key去检索value,而不是通过绝对地址(和顺序容器不同)
无序性:使用hash表存储,内部无序
Map : 每个值对应一个键值
键唯一性:不存在两个元素的键一样
动态内存管理:使用内存管理模型来动态管理所需要的内存空间
模版 1 2 3 4 5 6 template < class Key , class T , class Hash = hash<Key>, class Pred = equal_to<Key>, class Alloc = allocator< pair<const Key,T> > > class unordered_map;
一般只使用模板前2个参数<KEY, T> 即unordered_map<const Key, T> map;
迭代器 unordered_map的迭代器是一个指针,指向这个元素,通过迭代器来取得它的值。
1 2 3 4 5 6 7 unordered_map<Key, T>::iterator it; (*it).first; (*it).second; (*it); it -> first; key it -> second; T
构造函数
unordered_map的构造方式有几种: - 构造空的容器 - 复制构造 - 范围构造 - 用数组构造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 #include <iostream> #include <string> #include <unordered_map> using namespace std;typedef unordered_map<string, string> stringmap;stringmap merge (stringmap a, stringmap b) { stringmap temp (a) ; temp.insert (b.begin (), b.end ()); return temp; }int main () { stringmap first; stringmap second ({{"apple" , "red" }, {"lemon" , "yellow" }}) ; stringmap third ({{"orange" , "orange" }, {"strawberry" , "red" }}) ; stringmap fourth (second) ; stringmap fifth (merge(third, fourth)) ; stringmap sixth (fifth.begin(), fifth.end()) ; cout << "sixth contains:" ; for (auto &x : sixth) cout << " " << x.first << ":" << x.second; cout << endl; return 0 ; }
输出结果:
1 sixth contains : apple:red lemon:yellow orange:orange strawberry:red
size()
返回unordered_map的大小
empty()
为空返回true
不为空返回false,和用size() == 0判断一样。
find();
查找key所在的元素。
找到:返回元素的迭代器。通过迭代器的second属性获取值
没找到:返回unordered_map::end
insert()
复制插入(复制一个已有的pair的内容) 数组插入(直接插入一个二维数组) 范围插入(复制一个起始迭代器和终止迭代器中间的内容) 数组访问模式插入(和数组的[]操作很相似)
具体的例子可以看后面示例代码。
at();
查找key所对应的值 如果存在:返回key对应的值,可以直接修改,和[]操作一样。 如果不存在:抛出 out_of_range 异常.
erase()
通过位置(迭代器)
通过key
通过范围(两个迭代器
clear()
清空unordered_map
swap()
void swap(unordered_map& ump);
交换两个unordered_map(整个交换两个map中的所有元素)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 #include <iostream> #include <string> #include <unordered_map> using namespace std;void display (unordered_map<string, double > myrecipe, string str) { cout << str << endl; for (auto &x : myrecipe) cout << x.first << ": " << x.second << endl; cout << endl; }int main () { unordered_map<string, double > myrecipe, mypantry = { {"milk" , 2.0 }, {"flour" , 1.5 } }; pair<string, double > myshopping ("baking powder" , 0.3 ) ; myrecipe.insert (myshopping); myrecipe.insert (make_pair <string, double >("eggs" , 6.0 )); myrecipe.insert (mypantry.begin (), mypantry.end ()); myrecipe.insert ({{"sugar" , 0.8 }, {"salt" , 0.1 }}); myrecipe["coffee" ] = 10.0 ; display (myrecipe, "myrecipe contains:" ); unordered_map<string, double >::const_iterator got = myrecipe.find ("coffee" ); if (got == myrecipe.end ()) cout << "not found" ; else cout << "found " << got->first << " is " << got->second << "\n\n" ; myrecipe.at ("coffee" ) = 9.0 ; myrecipe["milk" ] = 3.0 ; display (myrecipe, "After modify myrecipe contains:" ); myrecipe.erase (myrecipe.begin ()); myrecipe.erase ("milk" ); display (myrecipe, "After erase myrecipe contains:" ); myrecipe.swap (mypantry); display (myrecipe, "After swap with mypantry, myrecipe contains:" ); myrecipe.clear (); display (myrecipe, "After clear, myrecipe contains:" ); return 0 ; }
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 myrecipe contains:salt : 0 .1 milk : 2 flour : 1 .5 coffee : 10 eggs : 6 sugar : 0 .8 baking powder: 0 .3 found coffee is 10 After modify myrecipe contains:salt : 0 .1 milk : 3 flour : 1 .5 coffee : 9 eggs : 6 sugar : 0 .8 baking powder: 0 .3 After erase myrecipe contains:flour : 1 .5 coffee : 9 eggs : 6 sugar : 0 .8 baking powder: 0 .3 After swap with mypantry, myrecipe contains:flour : 1 .5 milk : 2 After clear, myrecipe contains:
begin()
begin() : 返回开始的迭代器
begin(int n) : 返回n号bucket的第一个迭代器
end()
end(): 返回结束位置的迭代器
end(int n) : 返回n号bucket的最后一个迭代器
bucket()
返回通过哈希计算key所在的bucket
此处仅使用哈希计算确定bucket,不保证key一定存在bucket中!
bucket_count()
返回bucket的总数
bucket_size()
返回第i个bucket的大小
此位置的桶子里的元素数量,但是函数并不会判断n是否在count范围内)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream> #include <string> #include <unordered_map> using namespace std;int main () { unordered_map<string, string> mymap = { {"house" , "maison" }, {"apple" , "pomme" }, {"tree" , "arbre" }, {"book" , "livre" }, {"door" , "porte" }, {"grapefruit" , "pamplemousse" } }; cout << "mymap contains:" ; for (auto it = mymap.begin (); it != mymap.end (); ++it) cout << " " << it->first << ":" << it->second; cout << endl; unsigned n = mymap.bucket_count (); cout << "mymap has " << n << " buckets.\n" ; for (unsigned i = 0 ; i < n; ++i) { cout << "bucket #" << i << "'s size:" << mymap.bucket_size (i) << " contains: " ; for (auto it = mymap.begin (i); it != mymap.end (i); ++it) cout << "[" << it->first << ":" << it->second << "] " ; cout << "\n" ; } cout << "\nkey:'apple' is in bucket #" << mymap.bucket ("apple" ) << endl; cout << "\nkey:'computer' is in bucket #" << mymap.bucket ("computer" ) << endl; return 0 ; }
输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 mymap contains: door:porte grapefruit:pamplemousse tree:arbre apple:pomme book:livre house:maisonmymap has 7 buckets.bucket #0 's size:2 contains: [book:livre] [house:maison] bucket #1 's size:0 contains:bucket #2 's size:0 contains:bucket #3 's size:2 contains: [grapefruit:pamplemousse] [tree:arbre] bucket #4 's size:0 contains:bucket #5 's size:1 contains: [apple:pomme] bucket #6 's size:1 contains: [door:porte] key :'apple' is in bucket #5 key :'computer' is in bucket #6