您的位置:首页 > 其它

vs 2003 中hash_map使用方法

2007-06-15 23:53 615 查看
vc 2003 中的hash_map与SGI STL中的定义有所不同,sgi stl中那个hash_map是根据hash值进行比较,但是VS 2003中的这个hash_map的定义是这样的:
template <
class Key,
class Type,
class Traits=hash_compare<Key, less<Key> >,
class Allocator=allocator<pair <const Key, Type> >
>
class hash_map;
这里有一个比较类型Traits,默认值为hash_compare<Key, less<Key> >模板类型。

一、Traits揭秘:

MSDN中对Traits的描述如下:
The type which includes two function objects, one of class compare able to compare two element values as sort keys to determine their relative order and a hash function that is a unary predicate mapping key values of the elements to unsigned integers of type size_t. This argument is optional, and hash_compare<Key, less<Key> > is the default value.

就是说Traits中要包含两个function,一个function能根据比较两个Key,决定其相对位置,另一个function能将Key映射为一个唯一的unsigned int值(即Key的hash value)。

The hash_map orders the sequence it controls by calling a stored hash Traits object of class value_compare. This stored object may be accessed by calling the member function key_comp. Such a function object must behave the same as an object of class hash_compare<Key, less<Key> >. Specifically, for all values _Key of type Key, the call Traits(_Key ) yields a distribution of values of type size_t.

结合Traits的默认值 hash_compare的实现,看一下:
template<class _Kty,
class _Pr = std::less<_Kty> >
class hash_compare
{ // traits class for hash containers
public:
enum
{ // parameters for hash table
bucket_size = 4, // 0 < bucket_size
min_buckets = 8}; // min_buckets = 2 ^^ N, 0 < N

hash_compare()
: comp()
{ // construct with default comparator
}

hash_compare(_Pr _Pred)
: comp(_Pred)
{ // construct with _Pred comparator
}

size_t operator()(const _Kty& _Keyval) const
{ // hash _Keyval to size_t value
return ((size_t)hash_value(_Keyval));
}
bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const
{ // test if _Keyval1 ordered before _Keyval2
return (comp(_Keyval1, _Keyval2));
}

protected:
_Pr comp; // the comparator object
};

在hash_compare的实现中有两个重要函数:
size_t operator()(const _Kty& _Keyval) const
bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const
第一个即是对Key作hash运算,第二个是比较Key的大小。
在比较Key的函数中,使用了_Pr 类型的comp,_Pr的默认类型正是less<_Kty>

就是说即使我们定义了自己的Traits实现来代替hash_compare,也要定义相应的两个函数。
如在.net 2002中对string并没有定义相应的Traits,那么我们可以这样定义

using namespace std;
class string_hash
{
public:
enum
{ // parameters for hash table
bucket_size = 4, // 0 < bucket_size
min_buckets = 8
}; // min_buckets = 2 ^^ N, 0 < N

string_hash() {}
size_t operator()(const string& key) const
{
long h = 0;
for(int i=0; i<key.size(); ++i)
{
h += key[i];
}
return (size_t)h;
}

bool operator()(const string& key1, const string& key2) const
{
return (key1.compare(key2) < 0);
}
};
Usage:
//this is just a simple implementation demonstrates what need to be done for a
//hash functor. It's not optimized.
....
hash_map<std::string, int, string_hash> myMap;

二、使用自定义Key类型+默认的hash_compare

那么是不是当我们使用自定义的类型作Key时,就必须自己定义Traits呢?当然不是!怎样使用自定义类型Key时仍然使用默认的hash_compare呢?
在自定义Key类型中使用默认的hash_compare
我们可以看到
在函数 size_t operator()(const _Kty& _Keyval) const 的实现中,调用了hash_value(Key),该函数返回一个size_t,
在函数 bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const 的实现中,调用了comp(Key& k1, Key& k2)
所以如果我们想要使用自定义Key类型,并且仍然采用hash_compare作为Traits的默认值,必须:
1、对自定义Key类型实现hash_value函数
2、重载operator <函数
3、hash_value函数和重载operator<函数都应属于namespace stdext中

class MyKeyType
{
........
};
namespace stdext
{
size_t hash_value(MyKeyType & mykey)
{
......
}
bool operator <(MyKeyType &k1,MyKeyType &k2)
{
...
}
}

然后定义自己的hash_map: hash_map<MyKeyType, int> myMap;

三、替换hash_compare中的less<_Kty>
hash_compare默认采用了less<_Kty>作为其比较模板参数,我们可以把它替换成我们希望的比较模板,比如myGreater<_Kty>
在template less<class Type>中,重载了operator()函数,less定义如下:

template<class Type>
struct less
{ // functor for operator<
bool operator()(const Type& _Left, const Type& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};

我们的myGreater可以如下定义:
template<class Type>
struct myGreater
{
public:
bool operator()(const Type& _Left, const Type& _Right) const
{ // apply operator< to operands
return (_Left > _Right);
}
};
Usage:
HashMap<MyKey, MyValue, stdext::hash_compare<MyKey,myGreater<MyKey> > > mHashMap;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: