C++中使用STL的hashmap

我们就来分析一下hash_map的教程:


简单变量作为索引:
整形,实性,指针型,
hash_map<int, int >inthash;
inthash[1] = "123";
inthash[2] = "456";
int val = inthash[1];
int val = inthash[2];






hash_map<const char*, int >charhash;
charhash["a"] = 123;
charhash["b"] = 456;
char szinput[64] = "";
scanf("%s", szinput);
int val = charhash[szinput];
最终的结果无论输入任何字符串否无法找到对应的整数值,因为输入的字符串指针是szinput, 和"a"或"b"字符串常量指针永远不可能相等;
解决办法如下:
首先写一个仿函数charless()继承自函数基类binary_function(当然也可以不继承)
struct charless :public binary_function(const char*, const char, bool)
{
public:
result_type operate()(const first_argument_type&_left, const second_argument_type&_right) const
{
return (stricmp(_left, _right) < 0 ? true : false);
}
};
那么有了这个仿函数,我们就可以正确的使用字符穿hash_map了;




hash_map<const char*, int, hash_map<const char *, charless>> charhash
charhash["a"] = 123;
charhash["b"] = 456;
char szinput[64] = "";
scanf("%s", szinput);
int val = charhash[szinput];
那么这个时候,简单类型的使用方法介绍完毕:




另外:微软为标准的basic_string(string 的基类)提供了hash的方法:
虽然支持string 的hash; 而hash类却没有重载运算比较符,所以以前的hash_compare仍然无法工作:




struct string_less :public binary_function<const string, const string, bool>
{
public:
result_type operator()(const first_argument_type& _left, const second_argument_type&_right)const
{
return (_left.compare(_right) < 0 ? true : false);


}
};






好了,我们可以书写如下代码:
hash_map<int, string, compare<string, string_less>>stringhash
{
stringhash["a"] = 123;
stringhash["b"] = 456;
string strkey = "a";
int val = charhash[strkey];






}




对于微软的cstring,其重载了比较运算符,所以我么必须重写hash_compare放函数:
那么在头文件#include <atlstr.h>
中包含了 ,我们运用头文件就可以使用了;
下面我们来使用 hash_value()






inline size_t cstring_hash_value(const cstring &str)
{
size_t value = _HASH_SEED;
size_t size = str.getlength();
if (size > 0)
{
size_t temp = size / 16 + 1;
size -= temp;
for (size_t index = 0; index < size; i += temp)
{
value += (size_t)str[(int)index];
}
}
return value;
}


其次重写hash_compare()函数:




class cstring_hash_value :public hash_compare<cstring>
{
public:
size_t operator()(const cstring &_key)const
{
return (size_t)cstring_hash_value(_key);
}


bool operator()(const cstring & string1, const cstring& string 2)
{
return (comp(string1, string2));
}
};








上面的重载忽略了对于less()仿函数的应用:
因为cstring 具有比较运算符:
那么我们可以使用默认的less仿函数,在这里映射为comn()函数好了我么可以声明新的hash_map对象了:
hash_map<cstring, int, CString_compare >cstringhash


其余的操作是一样的
首先定义:
struct ihashable
{
virtual unsigned long hash_value()const = 0;
virtual bool operator <(const ihashable&val)const = 0;
virtual inthash&operator=(const inthash&val)const = 0;
};










让我们自己写的类都派生在这里:


class ctest :public ihashable
{
public:
int m_value;
cstring m_message;
public:
ctest()m_value(0)
{};
ctest(ctest& obj)
{
m_value = obj.m_value;
m_message = obj.m_message;
}
public:
virtual ihashable& operator =(const ihashable& val)
{
m_value = (ctest&).m_value;
m_message = (ctest&).m_message;
return *this;
}


virtual unsigned long hash_value() const
{






return (m_value ^ 0xdeadbeef);
}






virtual bool operator<(const ihashable&val)const
{
return (m_value < ((ctest&)val).m_value);


}
};




用这个类的对象作为hash索引工作如下:
因为接口规定了比较运算符:
所以这里可以使用标准的less放函数:
所以这里忽略




template<class _key>
class myhashcompare: public hash_compare<_key>
{
public:
size_t operator ()(const _key& __key)const{




return (_key.hash_value());
}
bool operator()(const _key&_key1, const _key&key2)
{




return true(compare(_key1, _key2);
}
};




下来就这样写:
Ctest test;
test.value = 123;
test.m_message = "this is a test ";
myhash[test] = 2005;




int val = myhash[test];




可以看到正确的数字被返回,
性能分析:
采用了内联代码和模板技术的hash_map在效率上应该是非常优秀的,但我们还需要注意如下几点:








经过查看代码,字符串索引会简单类型索引速度慢,自定义类型索引的索引的性能则和我们选择hashde 的内容有很大关系,简单为主,这是使用hash_mapde 基本原则。
可以重写hash_compair仿函数






inline  size_t ptchar_hash_value(const ptchar  str)
{
size_t value = _HASH_SEED;
size_t szie = _tcslen(str);
if (szie > 0)
{
size_t temp = (szie / 16) + 1;
size -= temp;
for (int index = 0; index < size; index += temp)
{
value += (size_t)str[(int)index];
}


}
return value;
}
class ptchar_hash_compare :public  stdext::hash_compare<PTCHAR>
{
public:
szie_t operator()(const PTCHAR _key) const
{
return ((size_t)ptchar_hash_compare(_key);
}
bool operator()(const PTCHAR _key1,const PTCHAR _key2)
{
return (_tcscmp(_key1, _key2));
}
};


stdext::hash_map<PTCHAR, long, ptchar_hash_compare>myhash;





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值