unordered_map的有序版本
ordered version of unordered_map?
在我下面的程序中,我目前使用unordered_map
只是因为我想要O(1)搜索/插入时间。但现在我想要订购这些物品。每次排序都非常低效。我的选择是什么?我读到hash_map
可以完成这项工作,但我读到的文章非常令人困惑,或者对我来说相当复杂。hash_map
的插入/搜索的复杂度是多少?它真的是有序的吗?如果有,它是在c++ 0x中定义的吗?我如何实现它?如果没有,我还能用什么?谢谢。
include <iostream>
#include <iterator>
#include <set>
#include <vector>
#include <unordered_map>
using namespace std;
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
template <typename C> struct ContainerHasher
{
typedef typename C::value_type value_type;
inline size_t operator()(const C & c) const
{
size_t seed = 0;
for (typename C::const_iterator it = c.begin(), end = c.end(); it != end; ++it)
{
hash_combine<value_type>(seed, *it);
}
return seed;
}
};
typedef std::set<int> my_set;
typedef std::vector<int> my_vector;
typedef std::unordered_map<my_set, my_vector, ContainerHasher<std::set<int>>> my_map;
typedef my_map::iterator m_it;
void print(my_map& data)
{
for( m_it it(data.begin()) ; it!=data.end(); ++it)
{
cout << "Key : ";
copy(it->first.begin(), it->first.end(), ostream_iterator<int>(cout, " "));
cout << " => Value: ";
copy (it->second.begin(),it->second.end(),ostream_iterator<int>(cout," "));
cout << endl;
}
cout << "---------------------------------------------------------------n";
}
int main()
{
my_vector v1,v2,v3;
for(int i = 1; i<=10; ++i)
{
v1.push_back(i);
v2.push_back(i+10);
v3.push_back(i+20);
}
my_set s1(v3.begin(),v3.begin()+3);
my_set s2(v1.begin(),v1.begin()+3);
my_set s3(v2.begin(),v2.begin()+3);
my_map m1;
m1.insert(make_pair(s1,v1));
m1.insert(make_pair(s2,v2));
m1.insert(make_pair(s3,v3));
print(m1);
my_set s4(v3.begin(),v3.begin()+3);
m_it it = m1.find(s4);
if(it != m1.end())
{
cout << endl << "found" << endl;
}
else
{
cout << endl << "Not found" << endl;
}
}
编辑:我以前使用std::map
,但我有大量的项目(以百万计)。所以,即使商品数量如此之多,如果我想订购,你们都推荐map
吗?
使用常规的std::map
。注意,这意味着你需要排序而不是散列。
unordered_map
是 hash_map
。"无序"只是捕获了概念上的差异,而不是实现上的差异,因此它是一个更好的名称。
如果您经常需要排序顺序,那么我建议切换到map
,这是一个有序的容器。插入和查找的复杂性现在是对数的,但默认情况下容器是排序的。
为了在插入时保持元素的有序,您需要使用(ordered) map,它的设计具有渐近log(N)的最坏情况的插入复杂度,这是任何基于比较的排序算法的最佳结果。
为了提供对现有元素的快速(平均)访问,您可能可能希望使用无序(哈希)映射。
如果这两种情况都很重要,您可以使用两个映射,手动或创建一些包装器容器类同时封装映射和有序映射。
然而,这个解决方案可能只有在读操作(明显!)比写操作更频繁的情况下才有用,并且在内存消耗方面有一些缺点(由于缓存和页面交换问题可能导致性能下降)。因此,无论如何,这个解决方案需要一些实验和分析。
同样,如果你的排序有一些细节,例如,你的元素是根据一个小集合中的一些"比率"值排序的(比如,1,2,…10),特定的排序算法可能比map更好(因为这种排序可能不需要基于比较)
[edit](严格来说,我最后一个按小范围值排序的例子与std::map的可能使用不兼容,因为对于大量的元素,它显然不会产生严格的弱顺序。我没有删除它,因为它有时在某些应用程序中很有用)
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 使用一个考虑到std::map中键值的滚动或换行的键
- 导入库可以跨dll版本工作吗
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 允许从 std::map 的密钥窃取资源?
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 不同的Visual Studio版本中缺少.dll
- 用符号版本替换对函数的所有调用
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 我需要分发哪些版本的可再分发文件
- C++11 功能 std::map::at 编译旧版本的C++
- C++旧版本(不是 C++11)-- map -> 覆盖哈希代码
- 在新版本的 gcc 上返回隐式不可复制结构的 std::map 时出现编译错误
- XML RPC - 如何在C++版本的 XMLRPC-C 库中包装、返回和获取 vector<map<string、string> > 的对象?