VC散列表
vc下有2个版本的散列表类,hash_map和unordered_map,hash_map位于stdext命名空间,unordered_map在std命名空间(vs2008及其之后的版本可用),官方推荐使用unordered_map,前者是一个旧的非标版本。
2者使用起来很类似,但构造函数有明显不同。 在使用int之类的值类型作为key的情况下,后几个参数可以使用默认值,无需提供hash function和compare function。但如果需要特殊类型作为散列键值的情况用起来就麻烦很多,比如用字符串string作为散列键值(但如果include了<string>也是无需提供hash function和compare function,很方便)。
template<
class Key,
class Ty,
class Hash = std::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator<std::pair<const Key, Ty> > >
class unordered_map; template <
class Key,
class Type,
class Traits=hash_compare<Key, less<Key> >,
class Allocator=allocator<pair <const Key, Type> > >
class hash_map;
散列表类有几个概念搞清楚后才能很好的理解这2个构造函数。key键值、value实值、hash值是哈希表最基本的概念,在存储value值的时候,散列表需要将key值转换为hash值(hash值会被用来当做数组下标使用),其类型为无符号整形。key值 --> hash值的映射函数就是hash函数,vc为一些类型的key提供了默认的hash函数,比如int和string。映射函数并不保证key与hash值的映射关系是一一对应的,可能出现多个key值映射到一个hash值的情况。此时我们需要比较函数来解决冲突,用来区分相同hash值下的不同key值。
回到上面的2个构造函数,unordered_map是比较容易理解的,第三个入参【class Hash = std::hash<Key>】,它所需要的类型其实是个函数对象,用来完成散列映射。默认使用了名为hash的函数对象。第四个参数【class Pred = std::equal_to<Key>】,所需要的类型也是函数对象,用来完成hash值冲突后的key值的比较。对这2个参数我们也可以使用自定义的函数对象,比如下面(假设key的类型为int)。另外,string类型比较特殊,后面另说。
struct hashMy
{
size_t operator()(int _Val) const{return _Val%;}
}; struct equalMy
{ // functor for operator==
bool operator()(const int _Left, const int _Right) const
{ // apply operator== to operands
return (_Left == _Right);
}
}; std::unordered_map<int,int,hashMy,equalMy> s3;
而hash_map类的构造函数则是由第三个入参完成hash函数和比较函数2个功能。其默认的函数对象的定义如下
template<class Key, class Traits = less<Key> >
class hash_compare
{
Traits comp;
public:
const size_t bucket_size = ;
const size_t min_buckets = ;
hash_compare( );
hash_compare( Traits pred );
size_t operator( )( const Key& _Key ) const;
bool operator( )(
const Key& _Key1,
const Key& _Key2
) const;
};
注意这个类没有使用equal_to来做hash值冲突后的key值的比较,而是默认使用less函数。据说这是为了提高冲突后的查找效率,当需要判断等于的时候通过!(a < b) && !(b < a)来实现.....自定义的方式如下,假设key是int型。
class hash_compare_my
{
public:
enum
{
bucket_size = ,
min_buckets =
};
size_t operator( )( const int& _Key ) const{return _Key%;}
bool operator( )( const int& _Key1,const int& _Key2 ) const
{
return (_Key1 < _Key2);
}
}; stdext::hash_map<int,int,hash_compare_my> t;
平时经常需要用到string作为key的情况,在不include<string>的情况下,unordered_map会编译失败,我们需要提供自定义的string比较函数,string的hash函数可以复用库中提供的string hash函数。
注意,有include<string> 的情况下不需要提供自定义的hash函数和比较函数。
struct equal_s
{
bool operator()(const std::string& s1,const std::string& s2)const
{
return s1.compare(s2) == ;
}
};
struct less_s
{
bool operator ()(const std::string & str1, const std::string & str2) const
{
return str1.compare(str2) < ;
}
};
std::unordered_map<std::string,int,std::hash<std::string>,equal_s> s;
stdext::hash_map<std::string,int,stdext::hash_compare<std::string,less_s> > s1;
最后,散列表的插入函数insert有多个重载版本,如果遇到插入的key已经存在则插入操作失败,注意批量插入的重载版本不会显式提示失败。
template<class InputIterator>
void insert(
InputIterator _First,
InputIterator _Last
); pair <iterator, bool> insert(
const value_type& _Val
);
VC散列表的更多相关文章
- 散列表(hash table)——算法导论(13)
1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...
- HashTable(散列表)
最近都在研究数据结构,关于hashtable,或者叫做散列表,过去一直不了解是什么东西,现在终于明白了. 所谓hashtable,就是某组key,通过某个关系(函数),得到一个与之对应的映射值(在计算 ...
- &11,散列表
#1,是什么? 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个 ...
- [转载] 散列表(Hash Table)从理论到实用(上)
转载自:白话算法(6) 散列表(Hash Table)从理论到实用(上) 处理实际问题的一般数学方法是,首先提炼出问题的本质元素,然后把它看作一个比现实无限宽广的可能性系统,这个系统中的实质关系可以通 ...
- [转载] 散列表(Hash Table)从理论到实用(中)
转载自:白话算法(6) 散列表(Hash Table)从理论到实用(中) 不用链接法,还有别的方法能处理碰撞吗?扪心自问,我不敢问这个问题.链接法如此的自然.直接,以至于我不敢相信还有别的(甚至是更好 ...
- [转载] 散列表(Hash Table) 从理论到实用(下)
转载自: 白话算法(6) 散列表(Hash Table) 从理论到实用(下) [澈丹,我想要个钻戒.][小北,等等吧,等我再修行两年,你把我烧了,舍利子比钻戒值钱.] ——自扯自蛋 无论开发一个程序还 ...
- Java学习笔记(二十)——Java 散列表_算法内容
[前面的话] 周末,本来打算找人去玩,结果没找到,所以我只好有学习了. 为什么会学习散列表,因为要使用HashMap?因为在做项目的时候,在服务器和客户端需要传输DTO,而传输的属性是动态增加的,所以 ...
- [Linux] Linux进程PID散列表
linux系统中每个进程由一个进程id标识,在内核中对应一个task_struct结构的进程描述符,系统中所有进程的task_struct通过链表链接在一起,在内核中,经常需要通过进程id来获取进程描 ...
- JavaScript数据结构——集合、字典和散列表
集合.字典和散列表都可以存储不重复的值. 在集合中,我们感兴趣的是每个值本身,并把它当作主要元素.在字典和散列表中,我们用 [键,值] 的形式来存储数据. 集合(Set 类):[值,值]对,是一组由无 ...
随机推荐
- Tomcat中HTTP与AJP区别
Tomcat: HTTP与AJP区别 Tomcat服务器通过Connector连接器组件与客户程序建立连接,Connector组件负责接收客户的请求,以及把Tomcat服务器的响应结果发送给客户. 默 ...
- Java 子类实例化对象的过程
子类实例化是否会实例化父类? 不会.父类在子类实例化过程中是并没有被实例化,java中new子类没有实例化父类,只是调用父类的构造方法初始化了,子类从父类继承来的属性,这个调用是子类的对象调用的父类的 ...
- 【51nod-1046】最大子矩阵和
一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值. 例如:3*3的矩阵: -1 3 -1 2 -1 3 -3 1 2 和最大的子矩阵是: 3 ...
- R-一页多图
https://blog.csdn.net/ailsa__/article/details/45932753
- 自定义控件之TagGroup
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/74907150 标签瀑布流布局! 实现方式有很多种. 继承LinearLayout 继承 ...
- VS2017 Product Key
Enterprise: NJVYC-BMHX2-G77MM-4XJMR-6Q8QF Professional: KBJFW-NXHK6-W4WJM-CRMQB-G3CDH
- MYSQL中防止插入重复记录的解决方案(无重复值更新)
说明:一般我们使用MYSQL插入记录时,类似于这样的语句: insert into table_name(email,phone,user_id) values(‘test9@163.com’,’99 ...
- sql_自连接,181,182,196,197
181. Employees Earning More Than Their Managers https://leetcode.com/problems/employees-earning-more ...
- Python错误TypeError: write() argument must be str, not bytes
2016-07-03 20:51:25 今天使用Python中的pickle存储的时候出现了以下错误: TypeError: write() argument must be str, not byt ...
- 洛谷 P3015 [USACO11FEB]最好的括号Best Parenthesis
传送门 题目大意:给出括号的得分标准. ()得分为1,如果A的得分为S(A),那么 (A)的得分为2*S(A). 题解:搜索 #include<iostream> #include< ...