我最近发现将调用C++中哈希映射的实现unordered_map.
当我抬起头,为什么他们不只是使用hash_map,我发现,显然有与实施的兼容性问题hash_map是unordered_map可以解决(更多关于它在这里).
该wiki页面没有提供更多信息,所以我想知道是否有人知道hash_map该unordered_map解决方案的一些问题.
我目前有很多代码,如下所示:
std::unordered_map<int,int> my_dict;
.
.
.
// If the key does exist in the dictionary
if(my_dict.count(key) == 1){
my_dict[key] = value;
}
// If its a new key
else{
my_dict.insert(std::make_pair(key,value));
}
Run Code Online (Sandbox Code Playgroud)
有没有什么方法可以通过每次覆盖值来加快速度?
首先,有人可以澄清在C++中是否使用[]运算符和unordered_map进行查找包装调用find()方法,或者使用[]运算符比find()更快?
其次,在下面的一段代码中,我怀疑在unordered_map中没有键的情况下,我正在通过该行执行第二次查找map[key] = value,以便在使用[]运算符时替换在那里创建的默认值钥匙不存在.
这是真的,如果是这样的话(可能通过使用指针或其他东西)我可能只在任何情况下执行一次查找(可能通过存储放置值的位置/从中读取值)和仍然实现相同的功能?显然,如果是这样,这将是一项有用的效率改进.
以下是修改后的代码摘录:
int stored_val = map[key]; // first look up. Does this wrap ->find()??
// return the corresponding value if we find the key in the map - ie != 0
if (stored_val) return stored_val;
// if not in map
map[key] = value;
/* second (unnecessary?) look up here to find position for newly
added key entry */
return value;
Run Code Online (Sandbox Code Playgroud) 似乎C++没有标准库中字符串的哈希函数.这是真的?
使用字符串作为unordered_map中的键的一个工作示例是什么,它将与任何c ++编译器一起使用?
如果std::unordered_map使用相同的(非相等的)键值对创建两个容器,但以不同的顺序插入(因此容器包含相同的元素,但可能在不同的顺序中),容器保证是相等的,根据等于运算符(operator==).我假设容器元素的哈希码和相等运算符满足其实现的所有必需约束.
我有一个unordered_map成员的以下类,并定义了一个哈希函数pair<int,int>
class abc
{public :
unordered_map < pair<int,int> , int > rules ;
unsigned nodes;
unsigned packet ;
};
namespace std {
template <>
class hash < std::pair< int,int> >{
public :
size_t operator()(const pair< int, int> &x ) const
{
size_t h = std::hash<int>()(x.first) ^ std::hash<int>()(x.second);
return h ;
}
};
}
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误:
error: invalid use of incomplete type ‘struct std::hash<std::pair<int, int> >
error: declaration of ‘struct std::hash<std::pair<int, int> >
error: type ‘std::__detail::_Hashtable_ebo_helper<1, std::hash<std::pair<int, int> >, …Run Code Online (Sandbox Code Playgroud) 为什么不std::unordered_map<tuple<int, int>, string>开箱即用?必须为tuple<int, int>例如定义散列函数是繁琐的
template<> struct do_hash<tuple<int, int>>
{ size_t operator()(std::tuple<int, int> const& tt) const {...} };
Run Code Online (Sandbox Code Playgroud)
构建一个以元组为键的无序映射(Matthieu M.)展示了如何自动执行此操作boost::tuple.有没有为c ++ 0x元组执行此操作而不使用可变参数模板?
当然这应该在标准:(
考虑C++中有序和无序的关联容器double.
是NaN有效的密钥类型吗?
对于有序的容器,我应该说"不",因为它不尊重严格的弱排序.
对于无序容器,我不知道.
以下是GCC 4.6.2中发生的情况:
#include <map>
#include <unordered_map>
#include <cmath>
#include <iostream>
#include <prettyprint.hpp>
int main()
{
typedef std::map<double, int> map_type; // replace by "unorderd_map"
map_type dm;
double d = std::acos(5); // a good nan
dm[d] = 2;
dm[d] = 5;
dm[d] = 7;
std::cout << "dm[NaN] = " << dm[d] << ", dm = " << dm << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
对于有序地图,我得到:
dm[NaN] = 7, dm = [(nan, 7)]
Run Code Online (Sandbox Code Playgroud)
对于无序地图,我得到:
dm[NaN] = 0, dm …Run Code Online (Sandbox Code Playgroud) 我有一个unordered_map使用字符串类型作为键:
std::unordered_map<string, value> map;
Run Code Online (Sandbox Code Playgroud)
提供std::hash专业化,也提供string合适的专业化operator==.
现在我还有一个"字符串视图"类,它是一个指向现有字符串的弱指针,避免了堆分配:
class string_view {
string *data;
size_t begin, len;
// ...
};
Run Code Online (Sandbox Code Playgroud)
现在,我希望能够使用string_view对象检查地图中是否存在密钥.不幸的是, std::unordered_map::find需要一个Key参数,而不是一般T参数.
(当然,我可以"推广"一个到一个string,但这会导致我想避免的分配.)
我喜欢的是类似的东西
template<class Key, class Value>
class unordered_map
{
template<class T> iterator find(const T &t);
};
Run Code Online (Sandbox Code Playgroud)
这将需要operator==(T, Key)并std::hash<T>()适当地定义,并将迭代器返回到匹配值.
有没有解决方法?
std::unordered_map::emplace和std::unordered_map::insertC++有什么区别?