使用GNU编译器时,可写成如下形式:
#include <hash_set>
#include <iostream>
struct student{
char* name;
int age;
char* city;
char* phone;
};
//自定义数据的比较函数
class stuequal{
public:
bool operator() (const student& a,const student& b){
return strcmp(a.city,b.city)==0; //不允许同名,name为键值
} //将name换为city测试下
};
//自定义数据的hash函数
//typedef unsigned int size_t;
struct stu_hash{
size_t operator()(const student& stu) const
{
unsigned long res = 0;
char* s=stu.city;
for( ; *s; ++s ){
res=5*res+*s;
}
return size_t(res);
}
};
//针对字符串的比较函数对象
class strequal{
public:
bool operator () (const char* a,const char* b)const{
return strcmp(a,b)==0;
}
};
int main(){
using namespace std;
hash_set<const char*,hash<const char*>,strequal> a;
a.insert("tongjin");
a.insert("cumirror");
a.insert("makelaugh");
a.insert("feiguodeyun");
// hash<const char*>默认提供的hash函数对象
hash_set<const char*,hash<const char*>,strequal>::const_iterator b=a.find("tongjin");
cout<<*b<<" is "<<(b!=a.end()?"present":"not present")<<endl;
// 对于自定义类型数据,使用hash相关容器时应构造hash函数对象、比较函数对象
// 注意区别hash函数对象与比较函数对象各自的作用
student s[]={
{"童进",23,"长沙","XXX"},
{"老大",23,"武汉","XXX"},
{"饺子",23,"福州","XXX"},
{"王老虎",23,"地球","XXX"},
{"周润发",23,"香港","XXX"},
{"周星星",23,"香港","XXX"}, //city重复
{"童进",23,"香港","XXX"} //name重复、city也有重复
};
hash_set<student,stu_hash,stuequal> c;
c.insert(s[0]);
c.insert(s[1]);
c.insert(s[2]);
c.insert(s[3]);
c.insert(s[4]);
c.insert(s[5]);
c.insert(s[6]);
// 注意hash容器并不能实现排序
for(hash_set<student,stu_hash,stuequal>::iterator i=c.begin();i!=c.end();i++){
cout<<i->name<<" "<<i->age<<" "<<i->city<<endl;
}
return 0;
}
注意:上面代码用VS编译器是不行的。
下面代码可以用VS编译运行
//MT.h
#ifndef _MT_H_
#define _MT_H_
#include <hash_set>
#include <iostream>
using namespace std;
using namespace stdext;
//自定义类型
struct CMT
{
CMT(int x):value(x){}
friend bool operator==(const CMT& lhs, const CMT& rhs)
{
return lhs.value == rhs.value;
}
friend ostream& operator<<(ostream& os, const CMT& rhs)
{
return os << rhs.value;
}
int value;
};
//自定义类型所对应的hash类型,里面要包含hashing function
struct HashCMT
{
// hashing function
size_t operator()(const CMT & key) const
{
return key.value;
}
//在VS中,比较函数是必须得放在这里的,不然报错
bool operator()(const CMT& lhs, const CMT& rhs)
{
return lhs.value == rhs.value;
}
static const size_t bucket_size=53u;//在vs中这是必须的
static const size_t min_buckets=53u;//在vs中这是必须的
};
//VS中再定义个比较对象是不对的,必须放在HashCMT中定义比较函数
struct EqualCMT
{
bool operator()(const CMT& lhs, const CMT& rhs)
{
return lhs.value == rhs.value;
}
};
#endif
//show_main.cpp
#include <hash_set>
#include <iostream>
#include "MT.h"
using namespace std;
using namespace stdext; //在Dev C++ 和Linux记得加上 using namespace __gnu_cxx;
void test1()
{
hash_set<string> hst; //
cout << hst.size() << endl;//为0
cout << hst.bucket_count() << endl; //为8
cout << hst.max_bucket_count() << endl; //为8,为何不是4291967291呢?
}
void test2()
{
// hash_set<CMT, EqualCMT, EqualCMT> hst; //这么写是错误的!!!
hash_set<CMT,HashCMT> hst;
cout << hst.size() << endl;//为0
cout << hst.bucket_count() << endl; //为自己定义的值
cout << hst.max_bucket_count() << endl; //为自己定义的值
for (int i=0; i<53; ++i)
hst.insert(CMT(i));
hash_set<CMT,HashCMT >::iterator it = hst.begin();
for (; it != hst.end(); ++it)
cout << *it << " " ; //输出结果为:0 4 16 20 32 48 52,为何是这个结果呢?
cout << endl;
}
int main()
{
// test1();
test2();
return 0;
}