SGI STL hash_set哈希集合容器

使用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;
}


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值