C++11中std::unordered_map的使用
unordered map is an associative container that contains key-value pairs with unique keys. Search, insertion, and removal of elements have average constant-time complexity. Internally, the elements are not sorted in any particular order,but organized into buckets. Which bucket an element is placed into depends entirely on the hash of its key. This allows fast access to individual elements, since once the hash is computed, it refers to the exact bucket the element is placed into.
unordered_map containers are faster than map containers to access individual elements by their key, although they are generally less efficient for range iteration through a subset of their elements.
unordered_map's generally use more memory. A map just has a few house-keeping pointers then memory for each object. Contrarily, unordered_map's have a big array (these can get quite big in some implementations) and then additional memory for each object. If you need to be memory-aware, a map should prove better, because it lacks the large array.
unordered_map is an associated container that stores elements formed by combination of key value and a mapped value. The key value is used to uniquely identify the element and mapped value is the content associated with the key. Both key and value can be of any type predefined or user-defined. Internally unordered_map is implemented using Hash Table,the key provided to map are hashed into indices of hash table that is why performance of data structure depends on hash function a lot but on an average the cost of look-up from hash table is O(1). In worst case unordered_map may require O(n) time but practically it is much faster and outperforms tree based maps.
std::map对应的数据结构是红黑树。红黑树是一种近似于平衡的二叉查找树,里面的数据是有序的。在红黑树上做查找、插入、删除操作的时间复杂度为O(logN)。而std::unordered_map对应哈希表,哈希表的特点就是查找效率高,时间复杂度为常数级别O(1), 而额外空间复杂度则要高出许多。所以对于需要高效率查询的情况,使用std::unordered_map容器,但是std::unordered_map对于迭代器遍历效率并不高。而如果对内存大小比较敏感或者数据存储要求有序的话,则可以用std::map容器。
下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
#include "unordered_map.hpp"
#include <iostream>
#include <string>
#include <unordered_map>
//////////////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/container/unordered_map
int test_unordered_map1()
{
// Create an unordered_map of three strings (that map to strings)
std::unordered_map<std::string, std::string> u = {
{ "RED", "#FF0000" },
{ "GREEN", "#00FF00" },
{ "BLUE", "#0000FF" }
};
// Iterate and print keys and values of unordered_map
for (const auto& n : u) {
std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n";
}
// Add two new entries to the unordered_map
u["BLACK"] = "#000000";
u["WHITE"] = "#FFFFFF";
// Output values by key
std::cout << "The HEX of color RED is:[" << u["RED"] << "]\n";
std::cout << "The HEX of color BLACK is:[" << u["BLACK"] << "]\n";
std::cout << "The u's size: " << u.size() << std::endl;
return 0;
}
/////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/unordered_map/unordered_map/at/
typedef std::unordered_map<std::string, std::string> stringmap;
stringmap merge(stringmap a, stringmap b) {
stringmap temp(a); temp.insert(b.begin(), b.end()); return temp;
}
int test_unordered_map2()
{
////////// at/size
std::unordered_map<std::string, int> mymap = { { "Mars", 3000 }, { "Saturn", 60000 }, { "Jupiter", 70000 } };
mymap.at("Mars") = 3396;
mymap.at("Saturn") += 272;
mymap.at("Jupiter") = mymap.at("Saturn") + 9638;
for (auto& x : mymap) {
std::cout << x.first << ": " << x.second << std::endl;
}
std::cout << "mymap.size() is " << mymap.size() << std::endl;
/////////// begin
std::unordered_map<std::string, std::string> mymap2 = { { "Australia", "Canberra" }, { "U.S.", "Washington" }, { "France", "Paris" } };
std::cout << "mymap2 contains:";
for (auto it = mymap2.begin(); it != mymap2.end(); ++it)
std::cout << " " << it->first << ":" << it->second;
std::cout << std::endl;
std::cout << "mymap2's buckets contain:\n";
for (unsigned i = 0; i < mymap2.bucket_count(); ++i) {
std::cout << "bucket #" << i << " contains:";
for (auto local_it = mymap2.begin(i); local_it != mymap2.end(i); ++local_it)
std::cout << " " << local_it->first << ":" << local_it->second;
std::cout << std::endl;
}
////////////// bucket
std::unordered_map<std::string, std::string> mymap3 = {
{ "us", "United States" },
{ "uk", "United Kingdom" },
{ "fr", "France" },
{ "de", "Germany" }
};
for (auto& x : mymap3) {
std::cout << "Element [" << x.first << ":" << x.second << "]";
std::cout << " is in bucket #" << mymap3.bucket(x.first) << std::endl;
}
/////////////// count
std::unordered_map<std::string, double> mymap4 = {
{ "Burger", 2.99 },
{ "Fries", 1.99 },
{ "Soda", 1.50 } };
for (auto& x : { "Burger", "Pizza", "Salad", "Soda" }) {
if (mymap4.count(x)>0)
std::cout << "mymap4 has " << x << std::endl;
else
std::cout << "mymap4 has no " << x << std::endl;
}
///////////////// erase
std::unordered_map<std::string, std::string> mymap5;
// populating container:
mymap5["U.S."] = "Washington";
mymap5["U.K."] = "London";
mymap5["France"] = "Paris";
mymap5["Russia"] = "Moscow";
mymap5["China"] = "Beijing";
mymap5["Germany"] = "Berlin";
mymap5["Japan"] = "Tokyo";
// erase examples:
mymap5.erase(mymap5.begin()); // erasing by iterator
mymap5.erase("France"); // erasing by key
mymap5.erase(mymap5.find("China"), mymap5.end()); // erasing by range
// show content:
for (auto& x : mymap5)
std::cout << x.first << ": " << x.second << std::endl;
////////////////////// find
std::unordered_map<std::string, double> mymap6 = {
{ "mom", 5.4 },
{ "dad", 6.1 },
{ "bro", 5.9 } };
std::string input;
std::cout << "who? ";
getline(std::cin, input);
std::unordered_map<std::string, double>::const_iterator got = mymap6.find(input);
if (got == mymap6.end())
std::cout << "not found";
else
std::cout << got->first << " is " << got->second;
std::cout << std::endl;
//////////////////// insert
std::unordered_map<std::string, double>
myrecipe,
mypantry = { { "milk", 2.0 }, { "flour", 1.5 } };
std::pair<std::string, double> myshopping("baking powder", 0.3);
myrecipe.insert(myshopping); // copy insertion
myrecipe.insert(std::make_pair<std::string, double>("eggs", 6.0)); // move insertion
myrecipe.insert(mypantry.begin(), mypantry.end()); // range insertion
myrecipe.insert({ { "sugar", 0.8 }, { "salt", 0.1 } }); // initializer list insertion
std::cout << "myrecipe contains:" << std::endl;
for (auto& x : myrecipe)
std::cout << x.first << ": " << x.second << std::endl;
std::cout << std::endl;
//////////////////// =
stringmap first = { { "AAPL", "Apple" }, { "MSFT", "Microsoft" } }; // init list
stringmap second = { { "GOOG", "Google" }, { "ORCL", "Oracle" } }; // init list
stringmap third = merge(first, second); // move
first = third; // copy
std::cout << "first contains:";
for (auto& elem : first) std::cout << " " << elem.first << ":" << elem.second;
std::cout << std::endl;
return 0;
}
//////////////////////////////////////////////////////
// reference: http://www.geeksforgeeks.org/unordered_map-in-stl-and-its-applications/
int test_unordered_map3()
{
// key will be of string type and mapped value will be of double type
std::unordered_map<std::string, double> umap;
// inserting values by using [] operator
umap["PI"] = 3.14;
umap["root2"] = 1.414;
umap["root3"] = 1.732;
umap["log10"] = 2.302;
umap["loge"] = 1.0;
// inserting value by insert function
umap.insert(std::make_pair("e", 2.718));
std::string key = "PI";
// If key not found in map iterator to end is returned
if (umap.find(key) == umap.end()) {
std::cout << key << " not found\n\n";
} else {// If key found then iterator to that key is returned
std::cout << "Found " << key << "\n\n";
}
key = "lambda";
if (umap.find(key) == umap.end())
std::cout << key << " not found\n";
else
std::cout << "Found " << key << std::endl;
// iterating over all value of umap
std::unordered_map<std::string, double>::iterator itr;
std::cout << "\nAll Elements : \n";
for (itr = umap.begin(); itr != umap.end(); itr++) {
// itr works as a pointer to pair<string, double> type itr->first stores the key part
// and itr->second stroes the value part
std::cout << itr->first << " " << itr->second << std::endl;
}
return 0;
}
GitHub:https://github.com/fengbingchun/Messy_Test
C++11中std::unordered_map的使用的更多相关文章
- C++11中std::function的使用
class template std::function is a general-purpose polymorphic function wrapper. Instances of std::fu ...
- C++11中std::move的使用
std::move is used to indicate that an object t may be "moved from", i.e. allowing the effi ...
- C++11中std::bind的使用
std::bind: Each argument may either be bound to a value or be a placeholder: (1).If bound to a value ...
- C++11中std::forward的使用 (转)
std::forward argument: Returns an rvalue reference to arg if arg is not an lvalue reference; If arg ...
- C++11中std::forward的使用
std::forward argument: Returns an rvalue reference to arg if arg is not an lvalue reference; If arg ...
- C++11中std::move、std::forward、左右值引用、移动构造函数的测试
关于C++11新特性之std::move.std::forward.左右值引用网上资料已经很多了,我主要针对测试性能做一个测试,梳理一下这些逻辑,首先,左值比较熟悉,右值就是临时变量,意味着使用一次就 ...
- 用C++11的std::async代替线程的创建
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...
- C++11 使用 std::async创建异步程序
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...
- (原创)用C++11的std::async代替线程的创建
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + ); t.join(); 但是线程毕竟是属于比较 ...
随机推荐
- springboot整合mybatis增删改查(三):mybatis逆向工程
上一篇已经把项目基本框架完善,接下来就是利用Mybatis Generator逆向工程进行mybatis的整合. 我们在创建项目开始的时候已经勾选web,mybatis,sql等,但是这些依赖还是不够 ...
- 戴尔 Latiteude E7240 i7-4600U
一.鲁大师各项数据 二.内存条 三.电池损耗 四.跑分
- python静态方法类方法属性方法
Python的静态方法和类成员方法都可以被类或实例访问,两者概念不容易理清,但还是有区别的: 1)静态方法无需传入self参数,类成员方法需传入代表本类的cls参数: 2)从第1条,静态方法是无法访问 ...
- macdown在mac OS 中的配置
macdown 用命令行打开.md文件 执行两条命令即可. sudo echo "open -a MacDown \$*" > /usr/local/bin/macdown ...
- CentOS 6.6下 BCM4312 802.11b/g无线网卡驱动安装
1.目前www.broadcom.com网站上最新版本为hybrid-v35,但此版本与2.6.32不匹配,无法识别验证密码,搜索网上说是要求升级内核,后根据http://www.dadclab.co ...
- GNU Radio: USRP2 and N2x0 Series
Comparative features list 相对性能清单 Hardware Capabilities: 1 transceiver card slot External PPS referen ...
- mysqlinsert触发器的创建
CREATE DEFINER=`wpsuper`@`%` TRIGGER `o2oinsert` BEFORE INSERT ON `t_s_o2o`FOR EACH ROW begin set Ne ...
- 汇编_指令_SUB
SUB是减法运算. 比如mov ax,2mov bx,1sub ax,bx 其中sub ax,bx就是ax中的值减bx中的值,等于1,然后把结果,也就是1,放入ax中.
- 五、jdk工具之jmap(java memory map)、 mat之四--结合mat对内存泄露的分析、jhat之二--结合jmap生成的dump结果在浏览器上展示
目录 一.jdk工具之jps(JVM Process Status Tools)命令使用 二.jdk命令之javah命令(C Header and Stub File Generator) 三.jdk ...
- Oracle Lock(Enqueues)
转载:http://www.cnblogs.com/Richardzhu/articles/2796540.html 数据库是一个多用户使用的共享资源.当多个用户并发地存取数据时,在数据库中就会产生多 ...