STL学习2常用容器2.7set/multiset

一、set容器

1、关联式容器,内部插入数据时候自动排序,不允许插入重复的key值

2、set/multiset容器不可以通过迭代器修改里面的元素,因为默认有了排序规则,其底层实现是红黑树,红黑树是平衡二叉树的一种

3、树的简单知识

   3.1二叉树:任何节点最多只允许有两个子节点,分别为左子节点和右子节

 

  3.2平衡二叉树:左子树与右子树的高度的绝对值不能大于1,且这棵树的子树也必须是平衡二叉树

  3.3二叉搜索树:比节点小的数在左节点比节点大的数在右节点

4、删除erase(key)

5、find 查找 查找容器中是否有响应的key数据,如果有返回迭代器,没有返回end的位置

6 、count(key)查找键key的元素个数 返回值为int  对于set而言结果是0或者1

7、lower_bound(keyElem) 返回第一个key>=keyElem元素的迭代器  若未找到返回end()

8、upper_bound(keyElem)返回第一个key>keyElem元素的迭代器 若未找到返回end()

9、equal_range(keyElem)返回容器中key与keyElem相等的上下限的两个迭代器 返回一个对组pair<iterator, iterator>,若未找到均 返回end()

10、对组声明方式

     10.1 第一种声明 pair<string, int>p(string("Tom"), 18);

     10.2 第二种声明 pair<string, int>p2 = make_pair("Jerry",20);

     10.3 访问第一个元素first ,第二个元素second,不是方法,相当于类

10、set容器只能插入不重复key值

   10.1 insert返回值是pair<iterator,bool>

    10.2bool代表了插入是否成功

11  对于set容器排序

   11.1 默认从小到大排序

   11.2 若要指定排序规则必须在插入之前,配合仿函数实现,set<int ,MyCompare>

   11.3 自定义数据类型,必须指定出排序规则

#include "pch.h"
#include <iostream>
#include<set>//set multiset头文件
#include<string>

using namespace std;

void printSet(const set<int>&s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
		cout << *it << " ";
	cout << endl;
}
void test01()
{
	set<int>s;
    //set 插入数据不是push/push_back,是insert
	s.insert(10);
	s.insert(30);
	s.insert(20);
	s.insert(50);
	s.insert(40);

	printSet(s);

	s.erase(10);

	printSet(s);
}

//查找
void test02()
{
	set<int>s;
	s.insert(10);
	s.insert(30);
	s.insert(20);
	s.insert(50);
	s.insert(40);
	//find(key)查找key是否存在 返回值为迭代器,若找到返回键值的位置,否则返回end()
	set<int>::iterator pos = s.find(300);
	if (pos != s.end())
	{
		cout << "找到了元素: " << *pos << endl;
	}
	else
	{
		cout << "未找到元素" << endl;
	}

	//count(key)查找键key的元素个数 返回值为int 
	//对于set而言结果是0或者1
	int num = s.count(10);
	cout << "10的个数为: " << num << endl;

	//lower_bound(keyElem) 返回第一个key>=keyElem元素的迭代器
	//若未找到返回end()
	set<int>::iterator res = s.lower_bound(30);
	if (res != s.end())
	{
		cout << "找到了lower_bound的值为: " << *res << endl;
	}
	else
	{
		cout << "未找到lower_bound的值" << endl;
	}

	//upper_bound(keyElem)返回第一个key>keyElem元素的迭代器
	//若未找到返回end()
	set<int>::iterator res2 = s.upper_bound(30);
	if (res2 != s.end())
	{
		cout << "找到了upper_bound的值为: " << *res2 << endl;
	}
	else
	{
		cout << "未找到upper_bound的值" << endl;
	}

	//equal_range(keyElem)返回容器中key与keyElem相等的上下限的两个迭代器
	pair<set<int>::iterator, set<int>::iterator> it=s.equal_range(30);
	if (it.first != s.end())
	{
		cout << "找到了equal_range中lower_bound的值为: " << *(it.first) << endl;
	}
	else
	{
		cout << "未找到equal_range中lower_bound的值" << endl;
	}
	if (it.second != s.end())
	{
		cout << "找到了equal_range的upper_bound的值为: " << *(it.second) << endl;
	}
	else
	{
		cout << "未找到equal_range的upper_bound的值" << endl;
	}


}

//对组声明
void test03()
{
	//第一种声明
	pair<string, int>p(string("Tom"), 18);
	cout << "姓名:"<< p.first << " 年龄: " << p.second<<endl;

	//第二种声明
	pair<string, int>p2 = make_pair("Jerry",20);//隐式转换将char*转换为string,反之不行
	cout << "姓名:" << p2.first << " 年龄: " << p2.second<<endl;
}

//set只能插入不重复key值,判断插入是否成功
//multiset可以插入重复的key值
void test04()
{
	set<int>s;
	pair<set<int>::iterator, bool> ret=s.insert(10);
	if (ret.second)
	{
		cout << "第一个插入成功" << endl;
	}
	else
	{
		cout << "第一个插入不成功" << endl;
	}
	pair<set<int>::iterator, bool> ret2 = s.insert(10);
	if (ret2.second)
	{
		cout << "第二个插入成功" << endl;
	}
	else
	{
		cout << "第二个插入不成功" << endl;
	}
	printSet(s);

	multiset<int>ms;
	ms.insert(10);
	ms.insert(10);

	for (multiset<int>::const_iterator it = ms.begin(); it != ms.end(); it++)
		cout << *it << " ";
	cout << endl;
}

//利用仿函数(函数对象) 指定set容器的排序规则
class myCompare
{
public:
	bool operator()(int v1, int v2)//重载()
	{
		return v1 > v2;
	}
};
void test05()
{
	set<int>s;
	s.insert(10);
	s.insert(30);
	s.insert(20);
	s.insert(50);
	s.insert(40);

	//默认排序是从小到大
	cout << "默认排序:";
	printSet(s);
	//插入之前 指定排序规则
	set<int, myCompare>s2;
	s2.insert(10);
	s2.insert(30);
	s2.insert(20);
	s2.insert(50);
	s2.insert(40);
	cout << "指定规则排序:";
	for (set<int, myCompare>::iterator it = s2.begin(); it != s2.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
//对于自定义数据类型,必须指定排序规则
//自定义数据
class  Person
{
public:
	Person(string name, int age)
	{
		m_Name = name;
		m_Age = age;
	}
	string m_Name;
	int m_Age;
};
//仿函数 排序规则指定
class MyComparePerson
{
public:
	bool operator()(const Person&p1, const Person&p2)
	{
		//年龄 升序
		return p1.m_Age < p2.m_Age;
	}
};


void test06()
{
	//对于自定义数据类型,必须指定排序规则
	set<Person,MyComparePerson>s;
	Person p1("aaa", 10);
	Person p2("bbb", 30);
	Person p3("ccc", 20);
	Person p4("ddd", 50);
	Person p5("eee", 40);

	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);
	s.insert(p5);


	for (set<Person,MyComparePerson>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << "姓名: " << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
	}
}
int main()
{
	//test01();
	//test02();
	//test03();
	//test04();
	//test05();
	test06();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值