hash_set和hash_map
来源:互联网 发布:多益网络 收入 编辑:程序博客网 时间:2024/06/05 23:58
1.hash_set集合容器
hash_set利用链式哈希表,进行数据的插入、删除和搜索。与set容器相同,不允许插入重复键值的元素。SGIC++哈希表是一个链式的结构,由表头和一系列单链组成。表头是一个数组式的线性表,用vector向量泛化出来。每个表头节点,称为桶(bucket),是一个指针域,指向链入的元素数据。表头的长度为向量容器的元素个数。
哈希表中数据的遍历,迭代器从0号桶、1号桶、2号桶,······,逐一遍历每个桶中的所有元素数据。
哈希表的数据检索,是通过哈希函数,计算出数据所存放的哈希地址,即算出数据在哪个桶的单链中,然后对单链中的每个数据进行比较,检索出所要的数据。因此,每个桶中的数据越少,比较的次数就越少,检索的效率越高。
实际应用中,具体将多少数据存入哈希表中是无法预先确定的,可以设定初始的哈希表长,随着数据量的增长,动态调整表长的大小。表长过长,会造成表头空间的浪费;表长过短,会造成每个桶下面链的元素过多,导致检索效率不高。为了使每个桶中的元素尽可能地少,SGI C++使用质数作为表长,并且使用表长作为求余运算的模,构造哈希函数。SGI C++ STL中,用作表长的的质数预先用一个28个元素的数组给出,这28个质数足够覆盖32bit的任意表长范围。
1.1创建hash_set对象
主要有以下几种方式。
(1) hash_set()
创建一个空的hash集合容器。哈希表长取默认值193,哈希函数对象为默认的hasn<Value>,键值比较实用默认的函数对象equal_to<Value>,内存分配器也取默认值。
hash_set<int> hs;
(2) hash_set(size_type n)
从质数列表中找出第一个大于等于n的质数作为表长,创建一个空的哈希集合容器,哈希函数对象、键值比较函数对象和内存分配器也取默认值。
hash_set<int> hs(300);//创建一个表长为389的哈希集合容器对象
(3) hash_set(size_type n,consthasher&h)
用大于等于n的质数作为表长,哈希函数对象为h,创建哈希集合容器对象。
structmyHash{
size_t operator()(int x)const{return x+2;}
};
hash_set<int,myHash> hs(300,myHash());
(4) hash_set(size_type n,consthasher&h,const key_equal&k)
用大于等于n的质数作为表长,哈希函数对象为h,键值比较函数对象k,创建哈希集合容器对象。
structstrEqual{
bool operator()(const char *s1,const char*s2)const
{
return strcmp(s1,s2)==0;
}
};
hash_set<char*,hash<char*>,strEqual>hash(300,hash<char*>(),strEqual());
(5) hash_set(const hash_set&)
拷贝构造函数。
hash_set<int> hs1;
hash_set<int> hs2(hs1);
1.2元素的插入
使用insert函数进行插入,哈希集合容器不允许插入重复的元素键值,否则插入失败。
hash_set<int> hs;
hs.insert(31);
hs.insert(23);
hs.insert(193);
1.3元素的删除
利用erase、clear函数可以删除某个迭代器位置上的元素、等于某个键值的元素、迭代器区间元素和容器上的所有元素。
1.4元素的遍历
利用迭代器实现哈希集合容器内元素的遍历。
#include <iostream>#include <hash_set>using stdext::hash_set;using namespace std;int main(){hash_set<int> hs;hs.insert(1);hs.insert(23);hs.insert(193);hash_set<int>::iterator begin,end;end=hs.end();for(begin=hs.begin();begin!=end;begin++){cout<<*begin<<endl;}system("pause");return 0;}
注意:在vs2008中使用hash_set需要用usingstdext::hash_set;因为hash_set是vs2008的一个扩展,并没有在标准C++库中。
1.5元素的搜素
利用find函数可以实现元素的搜索,返回搜索到的元素的位置。
#include <iostream>#include <hash_set>using stdext::hash_set;using namespace std;struct strEqual{bool operator()(const char* s1,const char* s2)const{return strcmp(s1,s2)==0;}};int main(){hash_set<char *,hash_set<char *>,strEqual> hs;hs.insert("apple");hs.insert("pear");hs.insert("banana");hs.insert("orange");//搜索元素bananahash_set<char*,hash_set<char*>,strEqual>::iterator i;i=hs.find("banana");cout<<"查找结果:"<<*i<<endl;system("pause");return 0;}
1.6其他常用函数
hash_set容器还有其他常用函数,empty、size、bucket_count、swap、resize和equal_range等函数可以获得容器的统计信息。
#include <iostream>#include <hash_set>using stdext::hash_set;using namespace std;int main(){hash_set<int> hs;hs.insert(10);hs.insert(30);hs.insert(100);hs.insert(23);cout<<hs.empty()<<endl;//是否为空cout<<hs.size()<<endl;//统计元素个数cout<<hs.bucket_count()<<endl;//统计表长system("pause");return 0;}
2.hash_map哈希映射容器
hash_map容器与map容器类似,都是将记录型的元素根据键值的大小将其插入容器,但是,hash_map使用的数据结构是哈希表,map使用的数据结构是红黑树。hash_map检索出来的元素是无序的,而map用迭代器遍历出来的元素是排序的,而且还提供了反向迭代器。
2.1创建hash_map对象
主要有以下几种方式。
(1) hash_map()
hash_map<int,char*> hm;
(2) hash_map(size_type n)
hash_map<int,char*> hm(300);
(3) hash_map(size_type n,consthasher& h)
struct myhash{
size_t operator()(int x)const{return x+2;}
};
hash_map<int,char*,myhash> hm(300,myhash());
(4) hash_map(size_type n,consthasher& h,const key_equal& k)
structstrequal{
bool operator()(const char* s1,const char*s2)const
{
return strcmp(s1,s2)==0;
}
};
hash_map<char*,int,hash<char*>,strequal>hm(300,hash<char*>(),strequal());
(5) hash_map(const hash_map&)
拷贝构造函数。
hash_map<int,char*> hm1;
hash_map<int,char*> hm2(hm1);
2.2元素的插入
利用insert函数可以将键值不重复的元素数据插入到容器的哈希表中。
#include<iostream>#include<hash_map>using stdext::hash_map;using namespace std;int main(){hash_map<const char*,float> hm;hm["apple"]=3.6f;hm["orange"]=2.0f;hm["banana"]=1.5f;cout<<"苹果价格"<<hm["apple"]<<"元/斤"<<endl;cout<<"橘子价格"<<hm["orange"]<<"元/斤"<<endl;cout<<"香蕉价格"<<hm["banana"]<<"元/斤"<<endl;system("pause");return 0;}
注:在vs2008中使用hash_map需要用usingstdext::hash_map;因为hash_map是vs2008的一个扩展,并没有在标准C++库中。
2.3元素的删除
利用erase函数和clear函数可以实现删除某个迭代器位置上的元素、等于某个键值的元素、迭代器区间上的元素和容器的所有元素。
2.4元素的遍历
利用迭代器可以实现元素的遍历。
#include<iostream>#include<hash_map>using stdext::hash_map;using namespace std;template<class Key, class NameType, class YearType, class AddrType>struct StudentRecord_tag{ //学生记录结构体struct StudentInfo_tag{ //学生信息结构体NameType name;YearType year;AddrType addr;};//提供类型信息typedef Key IdType;typedef StudentInfo_tag StudentInfo;//数据成员IdType id; //学号,键值StudentInfo sf; //学生信息,作映照数据};int main(void){//using namespace std;typedef StudentRecord_tag<int, char*, int, char*> StudentRecord;//学生数据StudentRecord srArray[] = { //3笔学生记录{ 192, "李强", 21, "北京" },{ 193, "王文", 29, "上海" },{ 191, "张三", 38, "深圳" }};//创建hash_map容器对象hm,管理学生记录hash_map<StudentRecord::IdType, StudentRecord::StudentInfo> hm;//装入3笔学生记录for(int j=0; j<3; j++)hm[srArray[j].id]=srArray[j].sf;//迭代器遍历元素hash_map<StudentRecord::IdType, StudentRecord::StudentInfo>::iterator i,iend;iend=hm.end();cout << "学号" << "姓名" << "年龄" << "地址" << endl; //Tab键分隔for(i=hm.begin(); i!=iend; i++)cout << (*i).first << ''<< (*i).second.name << ''<< (*i).second.year << ''<< (*i).second.addr << ''<< endl;system("pause");return 0;}
2.5元素的搜索
利用find函数可以搜索扫某个元素的位置,若不存在,则返回一个结束元素的位置。
// hash_map<StudentRecord::IdType,StudentRecord::StudentInfo>::iterator i;
i=hm.find(193);
2.6其他常用函数
与hash_set容器一样,hash_map提供了empty、size、bucket_count、swap、resize和equal_range等函数可以取得容器的统计数据。
#include<iostream>#include<hash_map>using stdext::hash_map;using namespace std;int main(void){//using namespace std;hash_map<int, char> hm;typedef pair<hash_map<int, char>::iterator, bool> ReturnPair;typedef pair<int, char> InsertPair;ReturnPair p;InsertPair p1(10, 'a'), p2(20, 'c'), p3(80, 'e');//插入p1p=hm.insert(p1);if(!p.second) cout << "插入p1失败\n";//插入p2p=hm.insert(p2);if(!p.second) cout << "插入p2失败\n";//插入p3p=hm.insert(p3);if(!p.second) cout << "插入p3失败\n";//打印统计数据cout << hm.empty() << endl; //打印是否为空(false为0)cout << hm.size() << endl; //打印元素个数(3)cout << hm.bucket_count() << endl; //打印表长(193)system("pause");return 0;}
- hash_set和hash_map
- C++中hash_map和hash_set的用法
- hash_set和hash_map自定义数据类型的处理
- hash_map 与 hash_set 详解
- hash_map hash_set命名空间
- hash_map 与 hash_set 详解
- hash_map 与 hash_set 详解
- hash_map 与 hash_set 详解
- hash_set,hash_map,hash_multiset,hash_multimap
- 在windows 和 linux下引入hash_set、hash_map头文件
- 在windows 和 linux下引入hash_set、hash_map头文件
- 在windows 和 linux下引入hash_set、hash_map头文件
- Linux包含hash_map和hash_set的not declared问题
- hash_map 与 hash_set 详解 ( 转 )
- 【转】hash_map 与 hash_set 详解
- set,map,hash_set,hash_map概览
- 【STL源码剖析读书笔记】【第5章】关联式容器之hash_set、hash_map、hash_multiset和hash_multimap
- 在windows 和 linux下引入hash_set、hash_map头文件(转)
- 黑马程序员-----OC学习之Foundation中的类
- 升级安卓开发环境到Android Studio和Genymotion
- 一个线程的死锁情况
- iptables 如何只开放80 和 22端口
- Nginx 优化指南
- hash_set和hash_map
- Linux查看系统开机时间
- 两个Activity之间跳转时,生命周期的执行顺序
- aauto学习系列之<5>:操作符
- poj-3087-Shuffle'm Up-模拟
- poj3296--Rinse(三分)
- 簡單使用animation
- Python对文件file的操作
- 常量指针与指针常量的区别