全部博文(512)
分类: C/C++
2006-07-01 20:14:15
hash_map基于hash table(哈希表)。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然而在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的。另外,编码比较容易也是它的特点之一。
其基本原理是:使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数,也叫做散列函数),使得每个元素的关键字都与一个函数值(即数组下标,hash值)相对应,于是用这个数组单元来存储这个元素;也可以简单的理解为,按照关键字为每一个元素“分类”,然后将这个元素存储在相应“类”所对应的地方,称为桶。
但是,不能够保证每个元素的关键字与函数值是一一对应的,因此极有可能出现对于不同的元素,却计算出了相同的函数值,这样就产生了“冲突”,换句话说,就是把不同的元素分在了相同的“类”之中。 总的来说,“直接定址”与“解决冲突”是哈希表的两大特点。
hash_map,首先分配一大片内存,形成许多桶。是利用hash函数,对key进行映射到不同区域(桶)进行保存。其插入过程是:
由此可见,要实现哈希表, 和用户相关的是:hash函数和比较函数。这两个参数刚好是我们在使用hash_map时需要指定的参数。
#include#include using namespace std; int main(){ hash_map<int, string> mymap; mymap[9527]="唐伯虎点秋香"; mymap[1000000]="百万富翁的生活"; mymap[10000]="白领的工资底线"; ... if(mymap.find(10000) != mymap.end()){ ... }
template <class _Key, class _Tp, class _HashFcn = hash<_Key>, class _EqualKey = equal_to<_Key>, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) > class hash_map { ... }
... hash_map<int, string> mymap; //等同于: hash_map<int, string, hash<int>, equal_to<int> > mymap;
struct hash<int> { size_t operator()(int __x) const { return __x; } };
struct hash<char*> struct hash<const char*> struct hash<char> struct hash<unsigned char> struct hash<signed char> struct hash<short> struct hash<unsigned short> struct hash<int> struct hash<unsigned int> struct hash<long> struct hash<unsigned long>
struct str_hash{ size_t operator()(const string& str) const { unsigned long __h = 0; for (size_t i = 0 ; i < str.size() ; i ++) __h = 5*__h + str[i]; return size_t(__h); } }; //如果你希望利用系统定义的字符串hash函数,你可以这样写: struct str_hash{ size_t operator()(const string& str) const { return return __stl_hash_string(str.c_str()); } };
现在可以对开头的"岳不群"进行哈希化了 . 直接替换成下面的声明即可:
mapnamemap; //改为: hash_map namemap;
你或许会问:比较函数呢?别着急,这里就开始介绍hash_map中的比较函数。
//本代码可以从SGI STL //先看看binary_function 函数声明,其实只是定义一些类型而已。 template <class _Arg1, class _Arg2, class _Result> struct binary_function { typedef _Arg1 first_argument_type; typedef _Arg2 second_argument_type; typedef _Result result_type; }; //看看equal_to的定义: template <class _Tp> struct equal_to : public binary_function<_Tp,_Tp,bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } };
struct mystruct{ int iID; int len; bool operator==(const mystruct & my) const{ return (iID==my.iID) && (len==my.len) ; } };
struct compare_str{ bool operator()(const char* p1, const char*p2) const{ return strcmp(p1,p2)==0; } };
typedef hash_map<const char*, string, hash<const char*>, compare_str> StrIntMap; StrIntMap namemap; namemap["岳不群"]="华山派掌门人,人称君子剑"; namemap["张三丰"]="武当掌门人,太极拳创始人"; namemap["东方不败"]="第一高手,葵花宝典";
现在知道如何选择了吗?权衡三个因素: 查找速度, 数据量, 内存使用。
这里还有个关于hash_map和map的小故事,看看:http://dev.csdn.net/Develop/article/14/14019.shtm
-bash-2.05b$ cat my.cpp #include#include #include using namespace std; //define the class class ClassA{ public: ClassA(int a):c_a(a){} int getvalue()const { return c_a;} void setvalue(int a){c_a;} private: int c_a; }; //1 define the hash function struct hash_A{ size_t operator()(const class ClassA & A)const{ // return hash (classA.getvalue()); return A.getvalue(); } }; //2 define the equal function struct equal_A{ bool operator()(const class ClassA & a1, const class ClassA & a2)const{ return a1.getvalue() == a2.getvalue(); } }; int main() { hash_maphmap; ClassA a1(12); hmap[a1]="I am 12"; ClassA a2(198877); hmap[a2]="I am 198877"; cout< return 0; } -bash-2.05b$ make my c++ -O -pipe -march=pentiumpro my.cpp -o my -bash-2.05b$ ./my I am 12 I am 198877
typedef hash_mapKeyMap;
来源
Description
Hash_map 是一种使用hash 关联容器,把Key 和value数据对应存储; Hash_map 同样是一个Pair 的关联容器,这意味着其元素类型是pair 由于hash_map在通过key值查找时具有很高的效率,所以hash_map对于一些互不相干的元素的存储非常有用。如果元素的某种顺序比较重要,使用map更合适一些。
Example
Definition Defined in the header hash_map, and in the backward-compatibility header hash_map.h. This class is an SGI extension; it is not part of the C++ standard.
const_reference
as the hash function.
These members are not defined in the and requirements, but are specific to hash_map.
Hash_map::iterator is not a mutable iterator, because hash_map::value_type is not . That is, if i is of type hash_map::iterator and p is of type
hash_map::value_type, then *i = p is not a valid expression. However, hash_map::iterator isn't a constant iterator either, because it can be used to modify the object that it points to. Using the same notation as above, (*i).second = p is a valid expression.
This member function relies on member template functions, which at present (early 1998) are not supported by all compilers. If your compiler supports member templates, you can call this function with any type of . If your compiler does not yet support member templates, though, then the arguments must either be of type const value_type* or of type
hash_map::const_iterator.
Since operator[] might insert a new element into the hash_map, it can't possibly be a const member function. Note that the definition of operator[] is extremely simple: m[k] is equivalent to
(*((m.insert(value_type(k, data_type()))).first)).second. Strictly speaking, this member function is unnecessary: it exists only for convenience.
struct eqstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) == 0;
}
};
int main()
{
hash_map<const char*, int, hash<const char*>, eqstr> months;
months["january"] = 31;
months["february"] = 28;
months["march"] = 31;
months["april"] = 30;
months["may"] = 31;
months["june"] = 30;
months["july"] = 31;
months["august"] = 31;
months["september"] = 30;
months["october"] = 31;
months["november"] = 30;
months["december"] = 31;
cout << "september -> " << months["september"] << endl;
cout << "april -> " << months["april"] << endl;
cout << "june -> " << months["june"] << endl;
cout << "november -> " << months["november"] << endl;
}
Template parameters
Parameter
Description
Default
Key
The hash_map's key type. This is also defined as hash_map::key_type.
Data
The hash_map's data type. This is also defined as hash_map::data_type.
HashFcn
The used by the hash_map. This is also defined as hash_map::hasher.
EqualKey
The hash_map key equality function: a that determines whether two keys are equal. This is also defined as hash_map::key_equal.
Alloc
The hash_map's allocator, used for all internal memory management.
Members
Member
Where defined
Description
key_type
The hash_map's key type, Key.
data_type
The type of object associated with the keys.
value_type
The type of object, pair
hasher
The hash_map's .
key_equal
that compares keys for equality.
pointer
Pointer to T.
reference
Reference to T
Const reference to T
size_type
An unsigned integral type.
difference_type
A signed integral type.
iterator
Iterator used to iterate through a hash_map.
const_iterator
Const iterator used to iterate through a hash_map.
iterator begin()
Returns an iterator pointing to the beginning of the hash_map.
iterator end()
Returns an iterator pointing to the end of the hash_map.
const_iterator begin() const
Returns an const_iterator pointing to the beginning of the hash_map.
const_iterator end() const
Returns an const_iterator pointing to the end of the hash_map.
size_type size() const
Returns the size of the hash_map.
size_type max_size() const
Returns the largest possible size of the hash_map.
bool empty() const
true if the hash_map's size is 0.
size_type bucket_count() const
Returns the number of buckets used by the hash_map.
void resize(size_type n)
Increases the bucket count to at least n.
hasher hash_funct() const
Returns the hasher object used by the hash_map.
key_equal key_eq() const
Returns the key_equal object used by the hash_map.
hash_map()
Creates an empty hash_map.
hash_map(size_type n)
Creates an empty hash_map with at least n buckets.
hash_map(size_type n,
const hasher& h)
Creates an empty hash_map with at least n buckets, using h
hash_map(size_type n,
const hasher& h,
const key_equal& k)
Creates an empty hash_map with at least n buckets, using h as the hash function and k as the key equal function.
template
Creates a hash_map with a copy of a range.
template
Creates a hash_map with a copy of a range and a bucket count of at least n.
template
Creates a hash_map with a copy of a range and a bucket count of at least n, using h as the hash function.
template
Creates a hash_map with a copy of a range and a bucket count of at least n, using h as the hash function and k as the key equal function.
hash_map(const hash_map&)
The copy constructor.
hash_map& operator=(const hash_map&)
The assignment operator
void swap(hash_map&)
Swaps the contents of two hash_maps.
pair
Inserts x into the hash_map.
template
Inserts a range into the hash_map.
void erase(iterator pos)
Erases the element pointed to by pos.
size_type erase(const key_type& k)
Erases the element whose key is k.
void erase(iterator first, iterator last)
Erases all elements in a range.
void clear()
Erases all of the elements.
const_iterator find(const key_type& k) const
Finds an element whose key is k.
iterator find(const key_type& k)
Finds an element whose key is k.
size_type count(const key_type& k) const
Counts the number of elements whose key is k.
pair
Finds a range containing all elements whose key is k.
pair
Finds a range containing all elements whose key is k.
data_type&
operator[](const key_type& k)
hash_map
See below.
bool operator==(const hash_map&,
const hash_map&)
Tests two hash_maps for equality. This is a global function, not a member function. New members
Member
Description
data_type&
operator[](const key_type& k)
Returns a reference to the object that is associated with a particular key. If the hash_map does not already contain such an object, operator[] inserts the default object data_type().
Notes
chinaunix网友2011-06-22 16:45:04
先看看alvin_lee 朋友做的解析,我觉得还是很正确的,从算法角度阐述了他们之间的问题! 实际上这个问题不光C++会遇到,其他所有语言的标准容器的实现及选择上都是要考虑的。做应用程序你可能觉得影响不大,但是写算法或者核心代码就要小心了。今天改进代码,顺便又来温习基础功课了。 还记得Herb Sutter那极有味道的《C++对话系列》么,在其中《产生真正的hash对象》这个故事里就讲了map的选择。顺便回顾一下,也讲一下我在实用中的理解。 选择map容器,是为了更快的从关键字查找到相关的对象。与使用list这样的线性表容器相比,一可以简化查找的算法,二可以使任意的关键字做索引,并与目标对象配对,优化查找算法。在C++的STL中map是使用树来做查找算法,这种算法差不多相当与list线性容器的折半查找的效率一样,都是O (log2N),而list就没有map这样易定制和操作了。 相比hash_map,hash_map使用hash表来排列配对,hash表是使用关键字来计算表位置。当这个表的大小合适,并且计算算法合适的情况下,hash表的算
chinaunix网友2009-12-15 10:44:41
删除所有偶数项,并打印出删除的项
1. vector/queue
正确方法1:
void erase(vector
chinaunix网友2009-07-20 10:40:46
//hash key 为string 类型举例
#include
chinaunix网友2009-07-20 10:39:57
1.HASH函数的声明问题
template
chinaunix网友2008-05-09 10:22:59
#include