c++STL标准模板库(关联式容器(set,multiset容器))

关联式容器(associate容器)是STL提供的容器的一种,其中元素与序列容器不同的是它已经排过序,它主要通过关键字的方式来提高查询效率。关联式容器包含set、multiset、map、multimap和hash table,本篇博客主要介绍set、multiset。

set 类模板


set类模板又称为集合类模板,一个集合对象像链表一样顺序的存储一组值。在一个集合中,集合元素既充当存储的数据,又充当数据的关键码。

可以使用如下的方式来创建set对象:

std::set<type,predicate> name;

该方式创建了一个名字为name,并且包含type类型数据的set空对象,该对象中未存储任何数据。该对象使用谓词所指的的函数来对集合中的元素进行排序。例如,要给整数创建一个空set对象,可以这么写:

std::set<int,std::less<int>> intest;

set类模板还可以进行如下的操作:

std::set<type,predicate> name(myset)
//这种方式使用了复制构造函数,从一个已经存在的集合myset中生成一个set对象。

std::set<type,predicate> name(first,last)
//这种方式从一定范围的元素中根据多重指示器所指示的起始与终止位置创建一个集合。

set类中的方式说明如下表

函数说明
begin返回指向集合中第一个元素的迭代器
clear清除集合中所有的元素
cout(x)返回集合中值为x的元素个数(计数)
empty如果集合为空,则返回true
end返回指向集合中最后一个元素的迭代器
equal_range(x)返回表示x下界和上界的两个迭代器,下界表示集合中第一个值等于x的元素,上界表示第一个值大于x的元素
erase(i)删除由迭代器i所指向的集合元素
erase(start,end)删除由迭代器start和迭代器end所指范围内的集合元素
erase(x)删除值为x的集合元素
find(x)返回一个指向x的迭代器,若x不存在,返回的迭代器为end所指的迭代器
insert(i,x)把x的值插入集合。x的插入位置从迭代器i所指明的元素出开始查找
insert(start,end)把迭代器start和end所指范围内值插入集合中(两个集合操作)
insert(x)把x的值插入集合元素
lower_bound(x)返回一个迭代器,指向位于x之前紧邻x的元素
upper_bound(x)返回一个迭代器,指向紧邻x之后的元素
max_size返回集合的最大容纳量
rbegin返回一个反向迭代器,指向集合的最后一个元素
rend返回一个反向迭代器,指向集合的第一个元素
size返回集合的大小
swap(set)交换两个集合的内容
value_comp返回value_compare类型的对象,该对象用于判断集合中的元素的先后次序

 

标注颜色的是序列容器中不存在,也就是关联容器中所独有的东西。

以下代码是对上面set类中的方式的具体应用:

//using begin()、end()、insert(x);

#include<iostream>
#include<set>
using namespace std;

int main()
{
	set<int> iset;
	iset.insert(3);		//使用insert(x)将x插入集合 
	iset.insert(1);
	iset.insert(8);
	iset.insert(6);
	cout<<"set:"<<endl;
	set<int>::iterator it;	//使用迭代器将set类中数据输出 
	for(it = iset.begin(); it != iset.end(); it++)
	{
		//使用begin(),end()函数分别指向set集合中的第一个元素和最后一个元素 
		cout<<" "<<*it;
	}
	return 0;
} 

其运行之后的结果可以看出该集合是将元素自动进行了排序输出的:

d6f63abe86484ee4a918d8c08200a211.png

 拓展训练:使用set容器存储一些学生的相关信息并输出:

#include<iostream>
#include<set>
using namespace std;
int main()
{
	set<string> iset;
	iset.insert("李牧歌");
	iset.insert("王俐元");
	iset.insert("王兰兰");
	iset.insert("张妍");
	int a[4]={1,2,3,4};
	set<string>::iterator it;
	cout<<"\t\t\t"<<"学生信息如下:" <<endl;
	cout<<"\t\t\t"<<"姓名"<<endl; 
	for(it=iset.begin();it!=iset.end();it++)
	cout<<"\t\t\t"<<*it<<endl;
	return 0;
} 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LmW5LmWaQ==,size_20,color_FFFFFF,t_70,g_se,x_16

 以下为常用的一些模板实例:

#include<iostream>
#include<set>
using namespace std;
int main()
{
	//Create two collection classes. 
	set<int> s1;
	cout<<"输入s1元素个数:"<<endl;
	int n;		cin>>n; 		//可以使用户自己输入数据 
	for(int i = 0; i < n; i++)
	{
		int x = 0;
		cin >> x;
		s1.insert(x);
	}
	int arry[]={2,45,5,24,3,21};		//用数组对其初始化 
	set<int> s2(arry,arry+6);
	set<int>::iterator it;
	cout << "s1:" << endl;
	for(it = s1.begin(); it != s1.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl; 
	cout << "new s2:" << endl;
	for(it = s2.begin(); it != s2.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl; 
	
	//using find.
	it = s2.find(21);		//使用find寻找s2中是否有21这个元素。 
	if(it == s2.end())
	cout << "not found" << endl;
	else
	cout << "found" << endl; 
	
	//using erase.
	s2.erase(3);	//删除元素3
	cout << "old1 s2:" << endl;
	for(it = s2.begin(); it != s2.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl; 
	
	//using lower_bound upper_bound
	it = s2.lower_bound(21);	//返回第一个出现的x的位置 
	cout << *it << endl;
	it = s2.upper_bound(24);	//返回最后一个出现x的位置 
	cout << *it << endl;
	//因为set容器不可以数据重复所以这个常使用在multiset和multimap中
	
	//using swap
	s1.swap(s2);
	cout << "old s1:" << endl;
	for(it = s1.begin(); it != s1.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl; 
	cout << "old2 s2:" << endl;
	for(it = s2.begin(); it != s2.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl; 
	
	//using clear empty
	s2.clear();
	cout << "old3 s2:" << endl;
	for(it = s2.begin(); it != s2.end(); it++)
	{
		cout << " " << *it;
	}
	cout << endl; 
	if(s2.empty())
		cout << "为空" << endl;
	else
		cout << "未空" << endl;
		
	return 0;
} 

运行结果如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LmW5LmWaQ==,size_20,color_FFFFFF,t_70,g_se,x_16

       multiset 类模板       


        multiset使程序能够顺序存储一组数据(即按大小顺序存储)。与集合类相似,多重集合的元素既可以作为存储的数据又可以作为数据的关键字。然而与集合类不同的是多重集合类可以包含重复的数据,创建语句与集合类的创建相同。

std::multiset<type,predicate> name;

该方式创建了一个名字为name,并且包含type类型数据的multiset空对象,该对象中未存储任何数据。该对象使用谓词所指的的函数来对集合中的元素进行排序。例如,要给整数创建一个空multiset对象,可以这么写:

std::multiset<int,std::less<int> > intset;

注意:less<int>表达式后要有空格。

std::multiset<type,predicate> name(mymultiset)
//这种方式使用了复制构造函数,从一个已经存在的集合myset中生成一个multiset对象。

std::multiset<type,predicate> name(first,last)
//这种方式从一定范围的元素中根据多重指示器所指示的起始与终止位置创建一个集合。

                 multiset类中的方法说明如表:

函数说明
begin返回指向集合中第一个元素的迭代器
clear清除集合中所有的元素 
cout(x)返回集合中值为x的元素个数(计数) 
empty如果集合为空,则返回true 
end返回指向集合中最后一个元素的迭代器 
equal_range(x)返回表示x下界和上界的两个迭代器,下界表示集合中第一个值等于x的元素,上界表示第一个值大于x的元素
erase(i)删除由迭代器i所指向的集合元素 
erase(start,end)删除由迭代器start和迭代器end所指范围内的集合元素 
erase(x)删除值为x的集合元素 
find(x)返回一个指向x的迭代器,若x不存在,返回的迭代器为end所指的迭代器 
insert(i,x)把x的值插入集合。x的插入位置从迭代器i所指明的元素出开始查找 
insert(start,end)把迭代器start和end所指范围内值插入集合中(两个集合操作)
insert(x)把x的值插入集合元素 
lower_bound(x)

返回一个迭代器,指向位于x之前紧邻x的元素 (即x前一个元素)

upper_bound(x)返回一个指向x之后的迭代器(最后出现的x的后一个元素)
max_size返回集合的最大容纳量 
rbegin返回一个反向迭代器,指向集合的最后一个元素 
rend返回一个反向迭代器,指向集合的第一个元素 
size返回集合的大小 
swap(set)交换两个集合的内容 
value_comp返回value_compare类型的对象,该对象用于判断集合中的元素的先后次序 

以下代码是对multiset的使用:

#include<iostream>
#include<set>
using namespace std;
int main()
{
	multiset<int> s1;
	int array[6] = {1,5,5,5,8,8};
	multiset<int> s2(array,array+6);
	s1.insert(2003);
	s1.insert(24);
	s1.insert(24);
	s1.insert(5);
	multiset<int>::iterator it;
	cout << "new s1:" << endl;
	for(it = s1.begin(); it != s1.end(); it++)
		cout << " " << *it;
	cout << endl;
	cout << "new s2:" << endl;
	for(it = s2.begin(); it != s2.end(); it++)
		cout << " " << *it;
	cout << endl;
	
	//use lower_bound upper_bound.
	it = s1.lower_bound(24);		//指向第一个出现的24
	cout << " " << *it << endl; 
	it = s1.upper_bound(24);		//指向最后出现的24的后一个元素 
	cout << " " << *it << endl;
	
	//use find
	cout << "请输入想在s2中寻找的数据" << endl;
	int i;
	cin >> i; 
	if(s2.find(i) == s2.end())
		cout<<"not found"<<endl;
	else
		cout<<"found"<<endl;
		
	return 0;	
}

运行结果如下: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LmW5LmWaQ==,size_20,color_FFFFFF,t_70,g_se,x_16

 实例:存储一些学生姓名,根据所输入姓名查找学习是否存在该学生。

#include<iostream>
#include<set>
using namespace std;
int main()
{
	multiset<string> s;
	cout<<"输入学校中有多少个学生:"<<endl;
	int n;	cin>>n;
	char name[25];
	for(int i = 0; i < n; i++)
	{
		cin>>name;
		s.insert(name);
	}
	multiset<string>::iterator it;
	cout<<"该学校学生有:"<<endl; 
	for(it = s.begin(); it != s.end(); it++)
	{
		cout<<" "<<*it;
	}
	cout<<endl;
	
	cout<<"请输入你要查找的学生姓名:"<<endl;
	cin>>name;
	if(s.find(name)==s.end())
		cout<<"该学生不存在"<<endl;
	else
		cout<<"该学生在该学校"<<endl;
		 
	return 0;	
}

运行结果如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LmW5LmWaQ==,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LmW5LmWaQ==,size_20,color_FFFFFF,t_70,g_se,x_16 

本篇博客到此结束,如果还有什么set容器和multiset容器的相关问题欢迎大家留言讨论,本人小白也渴望深入学习一些书本之外的只是,下篇博客周三更新哦(map,multimap容器)。 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小侯不躺平.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值