sgi std中直接使用hashtable中
想直接使用HASHTABLE需要对原代码进行一些改动。
1、比如说那几个构造函数分别都需要参数的。这显然是为了扩充方便,
但是我们一般使用缺省参数即可,因此直接将之删除。
2、缺省模板参数的改动
template<class _Val, class _Key=_Val,class _HashFcn=hashfcn<const _Val>,class _Extractkey=_Identity<_Val>,class _EqualKey=std::equal_to<_Val> hashtable
3、现在的使用就简单了。可以直接用typedef hashtable<int> inthash.就可以了
初始化的时候可以不用初始化也可以加上myinthash(100),就是一开始分配100个空间的VECTOR(实际上不是100)
4、HASHFUNC里面的HASH函数只有那么几个,
我们扩充一下
泛型的
template<class _Key>struct hashfcn
{
size_t operator()(const _Key s)
{return (size_t)s;}
}本来那个里面的之个是空的。我改掉了。
std::string的哈希函数写法。
一开始我想了好几种写法。
A、用C_str()这种做法有两个缺点,一是假如这个STRING里面含有空字符的话就得不到准确的字符串了。而且有额外的开销(在原来的字符串后面加个空字符,terminate()函数就是做这个事情的)
B、用at(int pos)对每个字符进行计算哈希函数,这样做效率也比较低,因为at()函数有个检测是不是越界的调用。
C、用iterator begin,end.
只不过这样做是不是大题小做了??
D、用const char *data()返回指针,再用size()确定大小。个人认为这是最好的办法。
具体代码
inline size_t __stl__hash__string(const sstd::string & __s)
{
unsigned long _h=1;
cosnt char *cr=__s.data();//这句话我一开始想放到for里面不过编译不通过不知道什么原因。
for(size_t i=1;i<__s.size();i++,cr++)
_h=5*_h+(*cr);
return _h;
}
template<>struct hashfcn<std::string>
{
size_t operator()(const std::string& _s){return __stl__hash__string(_s);}
}
template<>struct hashfcn<const std::string>
..同上吧。
注意的是上面的operator()里面的const std::string& _s这里面最好是写成引用。
也许有人会说,std::string不是引用计数吗?所以我这边写成引用和写成传值效率不是差不多吗?但是现在有的std::string没用引用计数,这样就惨了。这里面会把整个字符串都COPY一次。
5、分配器。
分配器假如不想用系统提供的分配器的话有两个函数要改掉
一个是_M_New_Node()
_M_del_Node()
这里面的两个函数大家自己写一下,
不过比较搞笑的话
_Hash_node我虽然不能new,但是我可以直接用delete??
以后又有问题可以问大家了,为什么在模板中一个模板类有可能可以delete,但是却不能用new,
注:微软的VC7。1中也有了hashtable(xhash文件中)
不过我不太喜欢那种做法,因为他将KEY直接固定在NODE里面了。