vs 2003 中hash_map使用方法

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; 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值