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");
//搜索元素banana
hash_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');
//插入p1
p=hm.insert(p1);
if(!p.second) cout << "插入p1失败\n";
//插入p2
p=hm.insert(p2);
if(!p.second) cout << "插入p2失败\n";
//插入p3
p=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的更多相关文章

  1. STL之hash_set和hash_map

    Contents 1 hash_set和hash_map的创建与遍历 2 hash_set和hash_map的查找 3 建议 一句话hash_set和hash_map:它们皆由Hashtable(St ...

  2. 容器使用的12条军规——《Effective+STL中文版》试读

    容器使用的12条军规——<Effective+STL中文版>试读     还 记的自己早年在学校学习c++的时候,老师根本就没有讲STL,导致了自己后来跟人说 起会C++的时候总是被鄙视, ...

  3. MMORPG大型游戏设计与开发(客户端架构 part4 of vegine)

    昨天是七夕,祝大家都过的快乐,希望这句迟到的问候不会造成大家心中的困扰.这一节讲到了前端比较重要的模块,性能以及调试异常模块.一个应用的性能往往是最核心的部分,就像人身体的各个器官一样,一小部分也不能 ...

  4. (转载)Autodesk面试技术题解答

    Autodesk面试技术题解答 By SmartPtr(http://www.cppblog.com/SmartPtr/)          近一年以来,AUTODESK的面试题在网上是闹的沸沸扬扬, ...

  5. Django 源码小剖: 更高效的 URL 调度器(URL dispatcher)

    效率问题 django 内部的 url 调度机制说白了就是给一张有关匹配信息的表, 这张表中有着 url -> action 的映射, 当请求到来的时候, 一个一个(遍历)去匹配. 中, 则调用 ...

  6. 学长们的求职血泪史(C/C++/JAVA)

    以下分三个方向讲解,每个方向都是一个学长独自撰稿. (一)  C语言篇 C语言求职血泪史 华为(实习):机试.一面.性格测试被鄙视.优招被鄙视.普招被鄙视 锐捷:笔试.面试莫名其妙被鄙视 创新工场:笔 ...

  7. [GeekBand] C++11~14

    一.关键字decltype 由对象得到对象的数据类型,例如 Complex  a(1,  2);     decltype(a)  b(3,  4);     declare type是让编译器去找到 ...

  8. c++20道面试题

    摘自传智播客论坛 问1:请用简单的语言告诉我C++ 是什么?答:C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛.C++支持多种编程范式 --面向对象编程.泛型编程和过程化编程. 其编程领 ...

  9. ZJOI2017 Day1

    私のZJOI Day1 2017-3-21 07:52:53 有人在暴力膜 苟-- 富贵 无相忘 ZJOI2017交流群 133135071 如果你足够厉害 如果你足够厉害 如果你足够厉害 其实完全可 ...

随机推荐

  1. 学习参考《高性能MySQL(第3版)》中文PDF+英文PDF

    学习mysql数据库时推荐看看mysql 领域的经典之作<高性能mysql(第3版)>,共分为16 章和6 个附录,内容涵盖mysql 架构和历史,基准测试和性能剖析,数据库软硬件性能优化 ...

  2. VS2015使用过程中参考过的有用链接

    VS中的第一个C程序:如何在Visual Studio 2015中编写C程序:https://www.bilibili.com/video/av5921799?from=search&seid ...

  3. 已知二叉树的中序序列为DBGEAFC,后序序列为DGEBFCA,给出相应的二叉树

    面对这种问题时我们该怎么解决? 今天写数据结构题.发现了一道总是碰见问题的题在这里我写了一种求解方法我自己称它为分层递归求解. 第一步通过观察我们知道后序遍历时最后一个是根节点A 在中序序列中A的左边 ...

  4. LeetCode_Construct Binary Tree from Inorder and Postorder Traversal

    一.题目 Construct Binary Tree from Inorder and Postorder Traversal My Submissions Given inorder and pos ...

  5. HDU 4462 Scaring the Birds (暴力枚举DFS)

    题目链接:pid=4462">传送门 题意:一个n*n的区域,有m个位置是能够放稻草人的.其余都是玉米.对于每一个位置(x,y)所放稻草人都有个作用范围ri, 即abs(x-i)+ab ...

  6. Xamarin大佬的地址

    https://www.cnblogs.com/hlx-blogs/p/7266098.html http://www.cnblogs.com/GuZhenYin/p/6971069.html

  7. Atcoder ABC 069 C - 4-adjacent D - Grid Coloring

    C - 4-adjacent Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statement We have ...

  8. java.sql.SQLException:错误 The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.

    错误 方法 添加后面的内容即可

  9. 【Codeforces Round #425 (Div. 2) A】Sasha and Sticks

    [Link]: [Description] [Solution] 傻逼题; 获取n/k; 对n/k的奇偶性讨论一下就好 [NumberOf WA] 0 [Reviw] [Code] #include ...

  10. 洛谷—— P1328 生活大爆炸版石头剪刀布

    https://www.luogu.org/problem/show?pid=1328 题目描述 石头剪刀布是常见的猜拳游戏:石头胜剪刀,剪刀胜布,布胜石头.如果两个人出拳一样,则不分胜负.在< ...