hash_map:
总结:http://blog.csdn.net/dodolzg/article/details/6381978
引入目的:
hash_map基于hash table(哈希表)。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。
原理:
hash_map,首先分配一大片内存,形成许多桶。是利用hash函数,对key进行映射到不同区域(桶)进行保存。
插入过程是:
1、得到key ,通过hash(key)函数得到对应key的hash值
2、存放key和value在对应hash值的桶内。
取值过程是:
1、给出key,通过hash(key)函数得到hash值
2、比较对应hash值的桶内元素是否与key相等,若都不相等,则没有找到。 否则取出相等记录的value。
——可以看出,hash和比较两个操作是hash_map的重点。
与map区别在于:
(1)构造函数。hash_map需要hash函数,等于函数;map只需要比较函数(小于函数).
(2)存储结构。hash_map采用hash表存储,map一般采用红黑树(RB Tree)实现。因此其memory数据结构是不一样的。
权衡是否使用hash_map:
权衡三个因素: 查找速度(注意还有hash的时间), 数据量, 内存使用。
常用函数:
(1)hash_map(size_type n) 如果讲究效率,这个参数是必须要设置的。n 主要用来设置hash_map 容器中hash桶的个数。桶个数越多,hash函数发生冲突的概率就越小,重新申请内存的概率就越小。n越大,效率越高,但是内存消耗也越大。
(2)const_iterator find(const key_type& k) const. 用查找,输入为键值,返回为迭代器。
(3)data_type& operator[](const key_type& k) . 当你使用[key ]操作符时,如果容器中没有key元素,这就相当于自动增加了一个key元素。因此当你只是想知道容器中是否有key元素时,你可以使用find。如果你希望插入该元素时,你可以直接使用[]操作符。
(4)insert 函数。在容器中不包含key值时,insert函数和[]操作符的功能差不多。但是当容器中元素越来越多,每个桶中的元素会增加,为了保证效率,hash_map会自动申请更大的内存,以生成更多的桶。因此在insert以后,以前的iterator有可能是不可用的。
(5)erase 函数。在insert的过程中,当每个桶的元素太多时,hash_map可能会自动扩充容器的内存。但在sgi stl中是erase并不自动回收内存。因此你调用erase后,其他元素的iterator还是可用的。
总结:http://blog.csdn.net/dodolzg/article/details/6381978
引入目的:
hash_map基于hash table(哈希表)。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。
原理:
hash_map,首先分配一大片内存,形成许多桶。是利用hash函数,对key进行映射到不同区域(桶)进行保存。
插入过程是:
1、得到key ,通过hash(key)函数得到对应key的hash值
2、存放key和value在对应hash值的桶内。
取值过程是:
1、给出key,通过hash(key)函数得到hash值
2、比较对应hash值的桶内元素是否与key相等,若都不相等,则没有找到。 否则取出相等记录的value。
——可以看出,hash和比较两个操作是hash_map的重点。
与map区别在于:
(1)构造函数。hash_map需要hash函数,等于函数;map只需要比较函数(小于函数).
(2)存储结构。hash_map采用hash表存储,map一般采用红黑树(RB Tree)实现。因此其memory数据结构是不一样的。
权衡是否使用hash_map:
权衡三个因素: 查找速度(注意还有hash的时间), 数据量, 内存使用。
常用函数:
(1)hash_map(size_type n) 如果讲究效率,这个参数是必须要设置的。n 主要用来设置hash_map 容器中hash桶的个数。桶个数越多,hash函数发生冲突的概率就越小,重新申请内存的概率就越小。n越大,效率越高,但是内存消耗也越大。
(2)const_iterator find(const key_type& k) const. 用查找,输入为键值,返回为迭代器。
(3)data_type& operator[](const key_type& k) . 当你使用[key ]操作符时,如果容器中没有key元素,这就相当于自动增加了一个key元素。因此当你只是想知道容器中是否有key元素时,你可以使用find。如果你希望插入该元素时,你可以直接使用[]操作符。
(4)insert 函数。在容器中不包含key值时,insert函数和[]操作符的功能差不多。但是当容器中元素越来越多,每个桶中的元素会增加,为了保证效率,hash_map会自动申请更大的内存,以生成更多的桶。因此在insert以后,以前的iterator有可能是不可用的。
(5)erase 函数。在insert的过程中,当每个桶的元素太多时,hash_map可能会自动扩充容器的内存。但在sgi stl中是erase并不自动回收内存。因此你调用erase后,其他元素的iterator还是可用的。
应用例子:
#include <ext/hash_map>
#include <string>
#include <iostream>
using namespace std;
using namespace __gnu_cxx;
class A{
public:
A(string a):m_a(a){}
string getValue() const{return m_a;}
private:
string m_a;
};
struct hash_A{
bool operator() (const A& s)const{
return (s.getValue())[0]-'a';
}
};
struct equal_A{
bool operator() (const A& s1, const A& s2)const{
return s1.getValue()==s2.getValue();
}
};
int main(){
hash_map<A, int, hash_A, equal_A> mymap;
A a1("mother"), a2("father");
mymap[a1] = 50;
mymap[a2] = 51;
cout << mymap[a1] << endl;
hash_map<A, int, hash_A, equal_A>::iterator iter;
for(iter=mymap.begin();iter!=mymap.end();iter++)
cout << (*iter).first.getValue() << " " << (*iter).second << endl;
if(mymap.find(a1)!=mymap.end()){
cout << "find!" << endl;
mymap.erase(a1);
}
if(mymap.find(a1)!=mymap.end())
cout << "find!" << endl;
else
cout << "missing!" << endl;
mymap.insert(pair<A,int>(a1,50));
cout << mymap.size() << endl;
system("pause");
return 0;
}