关于hash_map的使用和自定义类型

执假以为真 2007-07-29 11:04:09
上网找了很多资料,包括下面的连接等等:
http://www.stlchina.org/twiki/bin/view.pl/Main/STLDetailHashMap
写了个原型程序,但是打印的结果却不对,不知道为什么,请各位高手指点迷津!谢谢!

#include <iostream>
#include <hash_map>
#include <string>
using namespace std;
using stdext::hash_map;

class FenItem
{
public:
string fen;
string move;
enum {bucket_size = 1000, min_buckets = 1000 }; //何意?

public:
unsigned long operator () (const FenItem& f) const
{
char array[120];
memset(array, '\0', 120);
strncpy(array, (string(f.fen+f.move)).c_str(), strlen((string(f.fen+f.move)).c_str()));
size_t nKeyLength=strlen(array);
unsigned long h = 0, g;
char *arKey=array;
char *arEnd=arKey+nKeyLength;
while (arKey < arEnd)
{
h = (h << 4) + *arKey++;
if ((g = (h & 0xF0000000)))
{
h = h ^ (g >> 24);
h = h ^ g;
}
}
return h;
}

bool operator () (const FenItem& f1, const FenItem& f2) const
{
return ((f1.fen+f1.move) == (f2.fen+f2.move));
}
};

typedef hash_map<FenItem, int, FenItem> FenMap;

void main()
{
FenMap fm;
FenItem f1, f2;
f1.fen="Hello"; f1.move="World";
f2.fen="EE"; f2.move="FF";

fm[f1]=9; fm[f2]=20;
cout<<fm[f1]<<" "<<fm[f2]<<endl;
}
...全文
850 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
执假以为真 2007-07-31
  • 打赏
  • 举报
回复
我昨天后来就一直没有来了。现在成功了。原来要把==的判断改成<的判断啊!!真是令人意想不到!若是去看了它的源码,应该能做出来的。谢谢你!
systemthink 2007-07-31
  • 打赏
  • 举报
回复
學習學習!!
taodm 2007-07-30
  • 打赏
  • 举报
回复
map怎么用,hash_map怎么用,它们的对外接口相同。
如果出现问题,那么是你提供的hash函数不能真正hash造成的。
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
我原来用的是map,后来发现有问题,改用了hash_map。现在发现原先的问题是我自己程序的bug,经修改后,使用map效果还是很好的。
不过就本帖而言,问题尚未解决,或许用过hash_map的人一下就可以帮我解决了。谢谢up!
星羽 2007-07-30
  • 打赏
  • 举报
回复
up
taodm 2007-07-30
  • 打赏
  • 举报
回复
先去看《STL源码剖析》。
另外,除非是海量真随机数,否则hash_map不会比map有太多性能区别,建议你不要使用hash_map
taodm 2007-07-30
  • 打赏
  • 举报
回复
vc2005采用了3参格式的hash_map,devcpp是4参的。
你得用
bool operator () (const FenItem& f1, const FenItem& f2) const
{
return ((f1.fen+f1.move) < (f2.fen+f2.move));
}
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
哦,谢谢了!我去gcc下试试看。不过好在实际的问题已经通过map解决了,看来确实是一般只要map就够了。
taodm 2007-07-30
  • 打赏
  • 举报
回复
就改了你那么多,上面代码已经贴全了。
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
我机器上也有2005,也是不对。你不愿贴出来看看啊?哈哈。
taodm 2007-07-30
  • 打赏
  • 举报
回复
打印9 20
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
不过bug应该也不至于大到连这个最基本的hash_map也执行不正确或编译不通过吧?
如果你的执行正确,不管是什么环境下的,都不妨贴出来看看。不胜感谢。
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
哦,我说的VC7就是.net2003了,bug太多吗?这个倒不知道,谢谢!
taodm 2007-07-30
  • 打赏
  • 举报
回复
要支持MFC你就用完整版的vc2005。
VC7,bug太多,属不可用范围的。
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
VC2005express我几个月前就用了,好像不支持MFC,后来就没用了。你说的devcpp我当时也下载了下来用过一两次,感觉和以前用的VC6差别还满大,有些内部的类型都不一样,也就没有用了。
taodm 2007-07-30
  • 打赏
  • 举报
回复
VC7我建议你扔了。换VC2005express
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
是这样吗?我在VC7下面还是没有通过编译。你说你通过了编译,那么你运行的结果对吗?请把你的代码贴出来看看。我改后的如下,加了友元函数可是没通过编译。
#include <iostream>
#include <hash_map>
#include <string>

using std::string;
using std::cout;
using std::endl;
using stdext::hash_map;

class FenItem
{
public:
string fen;
string move;
enum {bucket_size = 1000, min_buckets = 1000 }; //何意?

public:
unsigned long operator () (const FenItem& f) const
{
char array[120];
memset(array, '\0', 120);
strncpy(array, (string(f.fen+f.move)).c_str(), strlen((string(f.fen+f.move)).c_str()));
size_t nKeyLength=strlen(array);
unsigned long h = 0, g;
char *arKey=array;
char *arEnd=arKey+nKeyLength;
while (arKey < arEnd)
{
h = (h << 4) + *arKey++;
if ((g = (h & 0xF0000000)))
{
h = h ^ (g >> 24);
h = h ^ g;
}
}
return h;
}

friend bool operator == (const FenItem& f1, const FenItem& f2);

};

bool operator == (const FenItem& f1, const FenItem& f2)
{
return ((f1.fen+f1.move) == (f2.fen+f2.move));
}

typedef hash_map<FenItem, int, FenItem> FenMap;

void main()
{
FenMap fm;
FenItem f1, f2, f3;
f1.fen="fdfd"; f1.move="Wosdasrld";
f2.fen="EE"; f2.move="FF";
f3.fen="Hello"; f3.move="World";

fm[f1]=9; fm[f2]=20; fm[f3]=456;
cout<<fm[f1]<<" "<<fm[f2]<<" "<<fm[f3]<<endl;
}
taodm 2007-07-30
  • 打赏
  • 举报
回复
2种方式,我用devcpp编译都通过了的。

“非成员函数怎么能重载==操作符呢?”你的基础比较差啊。
执假以为真 2007-07-30
  • 打赏
  • 举报
回复
1 如果只将我上面贴的程序中的
typedef hash_map<FenItem, int, FenItem> FenMap;
改为
typedef hash_map<FenItem, int, FenItem, FenItem> FenMap;
这是通不过编译的。

2 friend bool operator == (const FenItem& f1, const FenItem& f2)
{
return ((f1.fen+f1.move) == (f2.fen+f2.move));
}
非成员函数怎么能重载==操作符呢?

能把正确的源码完整的贴出来的,就给他分啦!
taodm 2007-07-30
  • 打赏
  • 举报
回复
friend bool operator == (const FenItem& f1, const FenItem& f2)
{
return ((f1.fen+f1.move) == (f2.fen+f2.move));
}
不该bool operator () (const FenItem& f1, const FenItem& f2) const
{
return ((f1.fen+f1.move) == (f2.fen+f2.move));
}
要么你得写typedef hash_map<FenItem, int, FenItem, FenItem> FenMap;
还是找本《STL源码剖析》认真看看吧。
加载更多回复(2)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧