c++学习笔记-提高篇-STL标准模板库4(set容器、map容器)

目录

set容器

一、set的基本概念

二、set构造和赋值

三、set大小和交换

四、set插入和删除

五、set容器查找和统计

六、set和multiset的区别

七、pair对组创建

 八、set容器排序

1.学习目标:

2.主要技术点:

3.示例一:set存放内置数据类型

4.示例二:set存放自定义数据类型

map容器

一、map的基本概念

二、map容器大小和交换

三、map容器插入和删除

四、map容器查找和统计

五、map容器排序


set容器

一、set的基本概念

1.简介:所有元素都会在插入时自动被排序

2.本质:set/multiset属于关联式容器,底层结构是用二叉树实现

3.set和multiset区别

set不允许容器中有重复元素

multiset允许容器中有重复元素

二、set构造和赋值

1.描述:创建set容器以及赋值

2.构造:

  • setst;                // 默认构造函数
  • set(const set &st)   //拷贝构造函数

3.赋值:

  • set& operator=(const set &st)   //重载等号操作符

4.示例

set容器插入数据时用insert

set容器插入数据会自动排序

#include
using namespace std;
#include

//set容器构造和赋值
void printSet(sets)
{
	for (set::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << "  ";
	}
	cout << endl;
}

void test01()
{
	sets1;
	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(30);
	s1.insert(30);
	s1.insert(30);

	//遍历容器
	//set容器的特点,所有元素被插入的时候会自动排序
	//set容器不允许插入重复的值
	printSet(s1);

	//拷贝构造
	set s2(s1);
	printSet(s2);

	//赋值操作
	set s3;
	s3 = s2;
	printSet(s3);

}

int main()
{
	test01();

	system("pause");
	return 0;
}

三、set大小和交换

1.描述:set容器的大小、是否为空、交换

2.构造:

  • size();                     //返回容器中元素的个数
  • empty();                 //判断容器是否为空
  • swap(st);               //交换两个集合容器

3.示例:

#include
#include
using namespace std;
//set容器  大小和交换

void printSet(set &s)
{
	for (set::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << "  ";
	}
	cout << endl;
}

//大小
void test01()
{
	set s1;
	
	//插入数据
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);	
	s1.insert(40);

	printSet(s1);

	//判断是否为空
	if (s1.empty())
	{
		cout << "s1为空" << endl;
	}
	else
	{
		cout << "s1不为空" << endl;
		cout << "s1的元素大小:" << s1.size()<< endl;

	}
}

//交换
void test02()
{
	set s1;
	s1.insert(10);
	s1.insert(30);
	s1.insert(20);
	s1.insert(40);

	set s2;
	s2.insert(200);
	s2.insert(100);
	s2.insert(400);
	s2.insert(300);

	cout << "交换前:" << endl;
	printSet(s1);
	printSet(s2);

	cout << "交换后:" << endl;
	s1.swap(s2);
	printSet(s1);
	printSet(s2);

}

int main()
{
	//test01();
	test02();
	system("pause");
	return 0;
}

四、set插入和删除

1.描述:set容器进行插入数据和删除数据

2.构造:

  • insert(elem);                     //在容器中插入元素
  • clear();                              //清除所有元素
  • erase(pos);                       //删除pos迭代器所指向的元素,返回下一个元素的迭代器
  • erase(beg,end);                //删除区间[beg,end]的所有元素,返回下一个元素的迭代器
  • erase(elem);                     // 删除容器中值为elem的元素

3.示例:

#include
using namespace std;
#include
#include

//set容器的插入和删除

void printSet(set &s)
{
	for (set::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << "  ";
	}
	cout << endl;
}

void test01()
{
	sets1;
	//插入
	s1.insert(20);
	s1.insert(10);
	s1.insert(40);
	s1.insert(30);

	//遍历
	printSet(s1);
	
	//删除
	s1.erase(s1.begin());
	printSet(s1);

	//删除重载版本
	s1.erase(30);
	printSet(s1);

	//清空
	//s1.erase(s1.begin(),s1.end());
	s1.clear();
	printSet(s1);

}	

int main()
{
	test01();

	system("pause");
	return 0;
}

五、set容器查找和统计

1.描述:对set容器进行查找数据以及统计数据

2.构造:

  • find(key);    //查找key是否存在,若存在,返回该元素的迭代器;若不存在,返回set.end()
  • count(key); //统计key的元素个数

3.示例:

#include
#include
using namespace std;
//set容器查找和统计
void test01()
{
	//查找
	sets1;

	//插入数据
	s1.insert(30);
	s1.insert(20);
	s1.insert(10);
	s1.insert(40);

	set::iterator pos = s1.find(40);
	if (pos != s1.end())  //s1.end()指向最后一个元素的下一个位置
	{
		cout << "找到元素:" << *pos << endl;
	}
	else
	{
		cout << "未找到元素" << endl;
	}
	//对于set而言,统计结果不是0就是1
	//对于multiset而言,统计结果大于1	
}

//统计
void test02()
{
	set s1;

	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(10);

	int num = s1.count(100);
	cout << "统计nus = " << num << endl;
}

int main()
{
	test02();
	system("pause");
	return 0;
}

注意:   count 对于set而言,统计结果不是0就是1;对于multiset而言,统计结果大于1

六、set和multiset的区别

1.区别:

  • set不可以插入重复数据,而multiset可以
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会检测数据,因此可以重复插入

2.示例:

#include
#include
using namespace std;

//set容器和multiset容器的区别
void test01()
{
	set s;
	pair::iterator, bool> ret = s.insert(10);
	if (ret.second)
	{
		cout << "第一次插入成功" << endl;
	}
	else
	{
		cout << "第一次插入失败" << endl;
	}

	pair::iterator,bool> ret2 = s.insert(10);
	if (ret2.second)
	{
		cout << "第二次插入成功" << endl;
	}
	else
	{
		cout << "第二次插入失败" << endl;
	}

	multisets1;
	//允许插入重复值
	s1.insert(20);
	s1.insert(20);
	for (multiset::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << endl;
	}
	cout << endl;
}

int main()
{
	test01();
	system("pause");
	return 0;
}

七、pair对组创建

1.功能描述:成对出现的数据,利用对组可以返回两个数组

2.两种创建方式:

  • pair p(value1,value2)
  • pair p = make_pair(value1,value2)

3.示例

#include
#include
using namespace std;

//pair对组的创建
void test01()
{
	//第一种方式
	pair p("Tom", 20);
	cout << "姓名:" << p.first << "   年龄:" << p.second << endl;

	pair p2 = make_pair("Jerry", 30);
	cout << "姓名:" << p2.first << "   年龄:" << p2.second << endl;

}


int main()
{
	test01();
	system("pause");
	return 0;
}

 八、set容器排序

1.学习目标:

  • set容器默认排序规则为从小到大,掌握如何改进排序规则

2.主要技术点:

  • 利用仿函数,可以改变排序规则 

3.示例一:set存放内置数据类型

#include
#include
using namespace std;

//set容器排序

class MyCompare
{
public:
	bool operator()(int v1, int v2) const
	{
		return v1 > v2;
	}
};


void test01()
{
	sets1;

	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(50);
	s1.insert(30);
	for (set::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << "  ";
	}
	cout << endl;

	//指定排序规则为从大到小
	sets2;
	s2.insert(10);
	s2.insert(40);
	s2.insert(20);
	s2.insert(50);
	s2.insert(30);
	for (set::iterator it = s2.begin(); it != s2.end(); it++)
	{
		cout << *it << "  ";
	}
	cout << endl;
}

int main()
{
	test01();

	system("pause");
	return 0;
}

注意仿函数中,operator()重载“()”时需要加const
class MyCompare
{
public:
    bool operator()(int v1, int v2) const
    {
        return v1 > v2;
    }
};
没加const报错的原因:通过在 operator() 函数后加上 const 修饰符,你告诉编译器这个函数不会修改对象的状态,因此可以在 const 对象上调用。这样应该能够解决与 C3848 错误相关的问题。

总结:利用仿函数指定set容器的排序规则

4.示例二:set存放自定义数据类型

#include
#include
#include
using namespace std;

//set容器排序,存放自定义数据类型
class Person
{
public:
	Person(string name,int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};

class comparePerson
{
public:
	bool operator()(const Person & p1, const Person & p2) const
	{
		//按照年龄降序
		return p1.m_Age > p2.m_Age;
	}
};

void test01()
{
	//自定义的数据类型  都会指定排序规则
	set s1;


	//创建Person对象
	Person p1("刘备", 24);
	Person p2("张飞", 14);
	Person p3("关羽", 50);
	Person p4("Jerry", 28);
	Person p5("Tom", 39);

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

	for (set::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << "姓名:" << it->m_Name << "  年龄:" << it->m_Age << endl;
	}
}

int main()
{
	test01();

	system("pause");
	return 0;
}

map容器

一、map的基本概念

1.简介:

  • map中所有元素都是pair
  • pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
  • 所有元素都会根据元素的键值自动排序

2.本质:

  • map/multimap属于关联式容器,底层结构是二叉树

3.优点:

  • 可以根据key值快速查找到value值

4.map/multimap区别

  • map不允许容器中有重复key值元素
  • multimap允许容器有重复key值元素

二、map构造和赋值

1.功能描述:对map容器进行构造和赋值操作

2.函数原型:

构造:

  • map mp;    //map默认构造
  • map(const map &mp);    //拷贝构造函数

赋值:

  • mp& operator = (const map &mp)   //重载等号运算符

3.示例:

#include
#include
using namespace std;

//map容器  构造和赋值
void printMap(map& m)
{
	for (map::iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << (*it).first << "   value = " << it->second << endl;
	}
	cout << endl;
}

void test01()
{
	//创建map容器
	map m;
	m.insert(pair(1, 10));
	m.insert(pair(2, 30));
	m.insert(pair(3, 30));

	printMap(m);

	//拷贝构造
	mapm2(m);
	printMap(m2);

	//赋值
	mapm3;
	m3 = m2;
	printMap(m3);
}

int main()
{
	test01();

	system("pause");
	return 0;
}

总结:map中所以元素是成对出现,插入数据时要使用对组

二、map容器大小和交换

1.功能描述:统计map容器大小以及交换map容器

2.函数原型

  • size();        //返回容器中元素的数目
  • empty();    //判断容器是否为空
  • swap();     //交换两个集合

3.示例:

#include
#include
using namespace std;

//map容器  大小和交换

void printMap(map& m)
{
	for (map::iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "k = " << it->first << "  value" << it->second << endl;
	}
	cout << endl;
}

void test01()
{
	//大小
	map m;
	m.insert(pair(1, 10));
	m.insert(pair(4, 30));
	m.insert(pair(3, 20));


	if (m.empty())
	{
		cout << "m为空" << endl;
	}
	else
	{
		cout << "m不为空" << endl;
		cout << "m大小:" << m.size() << endl;
		cout << "m内容:" << endl;
		printMap(m);
	}
}

void test02()
{
	map m;
	//for (int i = 1; i < 4; i++)
	//{
	//	m.insert(pair(i, i*10));

	//}
	//printMap(m);

	m.insert(pair(1, 10));
	m.insert(pair(3, 30));
	m.insert(pair(2, 20));

	mapm2;
	m2.insert(pair(4, 40));
	m2.insert(pair(6, 60));
	m2.insert(pair(3, 80));

	cout << "交换前:" << endl;
	cout << "m:" << endl;
	printMap(m);
	cout << "m2:" << endl;
	printMap(m2);
	cout << "-------------------------------" << endl;

	swap(m, m2);
	cout << "交换后:" << endl;
	cout << "m:" << endl;
	printMap(m);
	cout << "m2:" << endl;
	printMap(m2);

}

int main()
{
	//test01();
	test02();

	system("pause");
	return 0;
}

三、map容器插入和删除

1.功能描述:map容器进行插入数据和删除数据‘

2.函数原型:

  • insert(elem);    //在容器中插入元素
  • clear();             // 清除所以元素
  • erase(pos);      //删除pos迭代器所指的元素,返回下一个元素的迭代器
  • erase(beg,end);      //删除(beg,end)区间的元素,返回下一个元素的迭代器
  • erase(key);            //删除key值和其元素

3.示例:

#include
#include
using namespace std;

void printMap(map& m)
{
	for (map::iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << it->first << "  value = " << it->second << endl;
	}
	cout << endl;
}

void test01()
{
	mapm;
	
	//插入
	//第一种
	m.insert(pair(1, 10));

	//第二种
	m.insert(make_pair(2, 20));

	//第三种
	m.insert(map::value_type(0, 10));

	//第四种
	m[4] = 40;

	//cout << m[5] << endl;//没有的时候默认插入0

	printMap(m);

	//删除
	m.erase(m.begin());
	printMap(m);

	m.erase(2);//按照key删除
	printMap(m);

	m.erase(m.begin(),m.end());//清空
	printMap(m);

	m.insert(pair(0, 33));
	m.clear();//也是清空
	printMap(m);
}

int main()
{
	test01();

	system("pause");
	return 0;
}

四、map容器查找和统计

1.对map容器进行查找数据以及统计数据

2.函数原型

  • find(key);    //查找key是否存在,返回该键的元素的迭代器;若不存在,返回set.end()
  • count(key);  //统计key出现个数

3.示例:

#include
#include
using namespace std;

void test01()
{
	//查找
	mapm;
	m.insert(pair(1, 10));
	m.insert(pair(3, 30));
	m.insert(pair(2, 20));


	map::iterator pos = m.find(3);//find返回迭代器
	if (pos != m.end())
	{
		cout << "找到元素key = " << (*pos).first << "  value" << pos->second << endl;
	}
	else
	{
		cout << "未找到元素" << endl;
	}

	//统计   
	// map不允许插入重复key  对于count统计结果要么0,要么1
	//multimap允许插入重复key  对于count统计结果可以大于1
	int num = m.count(3);
	cout << "num = " << num << endl;

	multimap m2;
	m2.insert(pair(1, 10));	
	m2.insert(pair(1, 10));
	m2.insert(pair(1, 10));
	int num2 = m2.count(1);
	cout << "num2 = " << num2 << endl;


}

int main()
{
	test01();

	system("pause");
	return 0;
}

五、map容器排序

1.学习目标:map容器默认排序规则为  按照key值进行从小到大排序,学习如何改变排序规则

2.技术要点:

  • 利用仿函数,可以改变排序规则

3.示例一:内置数据类型排序

#include
#include
using namespace std;

class myCompare
{
public:
	bool operator()(int v1, int v2) const
	{
		//降序
		return v1 > v2;
	}
};

void test01()
{
	mapm;
	m.insert(make_pair(1, 10));
	m.insert(make_pair(2, 20));
	m.insert(make_pair(5, 50));
	m.insert(make_pair(3, 30));
	m.insert(make_pair(4, 40));

	cout << "默认从小到大排序:" << endl;
	for (map::iterator it = m.begin(); it != m.end(); it++)
	{
		cout << "key = " << it->first << "  value" << it->second << endl;
	}
	cout << endl;

	mapm2;
	m2.insert(make_pair(1, 10));
	m2.insert(make_pair(2, 20));
	m2.insert(make_pair(5, 50));
	m2.insert(make_pair(3, 30));
	m2.insert(make_pair(4, 40));
	cout << "改变从大到小排序:" << endl;
	for (map::iterator it = m2.begin(); it != m2.end(); it++)
	{
		cout << "key = " << it->first << "  value" << it->second << endl;
	}
	cout << endl;

}

int main()
{
	test01();

	system("pause");
	return 0;
	
}

3.示例二:自定义数据类型排序

#include
#include
using namespace std;

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;
};

class myCompare
{
public:
	bool operator()(int v1, int v2) const
	{
		return v1 > v2;
	}
};

void test01()
{
	map f;
	
	Person p1("刘备", 24);
	Person p2("小阿备", 2); 
	Person p3("关羽", 20);
	Person p4("小阿飞", 3);

	f.insert(make_pair(1, p1));
	f.insert(make_pair(4, p4));
	f.insert(make_pair(3, p3));
	f.insert(make_pair(2, p2));

	cout << "----------默认排序----------" << endl;
	for (map::iterator it = f.begin(); it != f.end(); it++)
	{
		cout << "key = " << it->first << "  姓名:" << it->second.m_Name << "  年龄:" << it->second.m_Age << endl;
	}
	cout << endl;

	cout << "----------从大到小排序----------" << endl;
	map f2;  //只能按照key值排序

	Person p11("刘备", 24);
	Person p12("小阿备", 2);
	Person p13("关羽", 20);
	Person p14("小阿飞", 3);

	f2.insert(make_pair(1, p11));
	f2.insert(make_pair(4, p14));
	f2.insert(make_pair(3, p13));
	f2.insert(make_pair(2, p12));

	for (map::iterator it = f2.begin(); it != f2.end(); it++)
	{
		cout << "key = " << it->first << "  姓名:" << it->second.m_Name << "  年龄:" << it->second.m_Age << endl;
	}
	cout << endl;
}

int main()
{
	test01();

	system("pause");
	return 0;

}

总结:自定义数据类型也只能按照key值排序,不能按照Person的年龄排序。

你可能感兴趣的:(c++,learning,notes,学习,笔记,c++)