C++笔记9:C++提高编程3:STL---函数对象&标准算法

0904

C++提高编程3:STL---函数对象&标准算法

  • 1、模板
  • 2、初识STL & 3、STL---常用容器(3.1-3.8)
    • 3.9 map multimap容器(二叉树结构---自动排序)
    • 3.10 STL案例2
  • 4、STL---函数对象(仿函数-重载`函数调用运算符()`)
    • 4.1 函数对象
    • 4.2 谓词
    • 4.3 内建函数对象
  • 5、STL---常用算法
    • 5.1 常用遍历算法
      • 5.1.1 for_each & 5.1.2 transform
    • 5.2 常用查找算法
      • 5.2.1 & 5.2.2 & 5.2.3:**返回值都是`迭代器`**
      • 5.2.4 & 5.2.5 & 5.2.6 (二分法查找&统计)
    • 5.3 常用排序算法
    • 5.4 常用拷贝和替换算法
    • 5.5 常用算数生成算法
    • 5.6 常用集合算法

1、模板

函数模板和类模板

2、初识STL & 3、STL—常用容器(3.1-3.8)

初始STL & STL—常用容器

3.9 map multimap容器(二叉树结构—自动排序)

(有区别)构造和赋值:set m1;//默认构造函数 set m2(m1);//拷贝构造函数 m3 = m1;//赋值
大小和交换:m1.size();//大小 m1.empty();//判空 m2.swap(m1);//交换
(有区别)插入和删除:m.insert(make_pair(6,25));//四种插入方式,推荐第二种 m.erase();//删除 m.clear();//清空
(有区别)查找和统计:m1.find(6);//返回的是迭代器 m1.count(6);//返回的是个数,找到就是1没找到就是0 注意:这里是按照Key值进行查找和统计的
排序:(和set容器类似)自动排序,既不是成员函数,也不是全局函数;可以利用仿函数自定义排序规则。

3.9.1 map 基本概念

map中所有元素都是pair对组:其中第一个元素为key(键值),起到索引作用,第二个元素为value(实值),可以根据key值快速找到value值。
map容器中的所有元素都会根据元素的键值Key自动排序!!!

map/multimap属于关联式容器,底层结构是用二叉树实现。二者的区别在于map不允许容器中有重复key值元素,而multimap允许(和set/multiset类似)。

3.9.2 构造与赋值 & 3.9.3 map大小和交换 & 3.9.4 map插入和删除 & 3.9.5 map查找和统计

//构造:
map mp; //map默认构造函数:
map(const map &mp); //拷贝构造函数
//赋值:
map& operator=(const map &mp); //重载赋值操作符
//大小:
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
//交换:
swap(st); //交换两个集合容器
//插入:
insert(elem); //在容器中插入元素。四种插入方式:推荐用放方式二m.insert(make_pair(1,20));和方式一m.insert(pair(10,111));,注意方式四不要乱用m[5] = 26;
//删除:
erase(key); //删除容器中值为key的元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
erase(beg, end);//删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
clear(); //清除所有元素。
//查找:
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
//统计:
count(key); //统计key的元素个数

示例:

//打印map m
void printMap(map<int,int>& m) {
   
	for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
   
		//cout << "键值Key = " << (*it).first << "\t实值Value = " << (*it).second << endl;
		cout << "键值Key = " << it->first << "\t实值Value = " << it->second << endl;
	}
}

int main() {
   

	pair<int, int> pr1(1, 10);
	pair<int, int> pr2(4, 20);
	pair<int, int> pr3(3, 30);
	pair<int, int> pr4(5, 40);
	pair<int, int> pr5(2, 50);
//默认构造函数
	map<int,int> m1;
	m1.insert(pr1);//插入
	m1.insert(pr2);
	m1.insert(pr3);
	m1.insert(pr4);
	m1.insert(pr5);
	//map容器会按照键值Key从小到大将元素进行排序:
	printMap(m1);//键值Key = 1     实值Value = 10
				 //键值Key = 2     实值Value = 50
				 //键值Key = 3     实值Value = 30
				 //键值Key = 4     实值Value = 20
				 //键值Key = 5     实值Value = 40
//判空+大小
	if (m1.empty())
		cout << "容器为空!!!" << endl;
	else
		cout << "容器非空,大小为:" << m1.size() << endl;//5
//交换
	pair<int, int> pr11(11, 16);
	pair<int, int> pr12(14, 26);
	pair<int, int> pr13(13, 36);
	pair<int, int> pr14(15, 46);
	pair<int, int> pr15(12, 56);
	
	map<int, int> m4;
	m4.insert(pr11);
	m4.insert(pr12);
	m4.insert(pr13);
	m4.insert(pr14);
	m4.insert(pr15);

	cout << "交换前:" << endl;
	printMap(m1);//
	cout << endl;
	printMap(m4);//
	cout << endl;
	m1.swap(m4);//交换
	cout << "交换后:" << endl;
	printMap(m1);//
	cout << endl;
	printMap(m4);//
	cout << endl;

//拷贝构造函数
	map<int, int> m2(m1);
	printMap(m2);//结果如下:
				//键值Key = 11    实值Value = 16
				//键值Key = 12    实值Value = 56
				//键值Key = 13    实值Value = 36
				//键值Key = 14    实值Value = 26
				//键值Key = 15    实值Value = 46
	cout << endl;
//清空
	m2.clear();
//插入
	//插入方式一:(前面的例子用的就是这个)
	m2.insert(pair<int,int>(10,111));
	//插入方式二:(这种比较简单,推荐)
	m2.insert(make_pair(8,126));
	//插入方式三:(不建议)
	m2.insert(map<int,int>::value_type(9,168));
	//插入方式四:不建议用[]来插入数据,但可以用来访问value,比如cout<
	m2[6] = 139;

	printMap(m2);//结果如下:
				//键值Key = 6     实值Value = 139
				//键值Key = 8     实值Value = 126
				//键值Key = 9     实值Value = 168
				//键值Key = 10    实值Value = 111
	cout << endl;
	//利用[Key]来输出Value值
	cout << "m2[10] = " << m2[10] << endl;//111
	//如果容器中没有Key为3的元素,就会创建一个元素插到容器中,对应的Value值为0
	//这就是为什么不建议用插入方式四的原因,想要利用[]输出元素的value值也要小心:要确保容器中有对应的Key值
	cout << "m2[3] = " << m2[3] << endl;//0
	printMap(m2);//结果如下:
			//键值Key = 3     实值Value = 0
			//键值Key = 6     实值Value = 139
			//键值Key = 8     实值Value = 126
			//键值Key = 9     实值Value = 168
			//键值Key = 10    实值Value = 111
	cout << endl;


//赋值
	map<int, int> m3;
	m3 = m1;
	printMap(m3);//结果如下:
				//键值Key = 11    实值Value = 16
				//键值Key = 12    实值Value = 56
				//键值Key = 13    实值Value = 36
				//键值Key = 14    实值Value = 26
				//键值Key = 15    实值Value = 46
	cout << endl;
//删除
	//①删除某个元素
	m3.erase(12);
	m3.erase(14);
	m3.erase(3);//没有key值为3的元素,
	printMap(m3);//结果如下:
			//键值Key = 11    实值Value = 16
			//键值Key = 13    实值Value = 36
			//键值Key = 15    实值Value = 46
	cout << endl;
	m3.insert(make_pair(6,20));
	m3.insert(make_pair(9, 139));
	printMap(m3);//结果如下:
			//键值Key = 6     实值Value = 20
			//键值Key = 9     实值Value = 139
			//键值Key = 11    实值Value = 16
			//键值Key = 13    实值Value = 36
			//键值Key = 15    实值Value = 46
	cout << endl;
	//②删除某个位置的元素
	m3.erase(m3.begin());
	printMap(m3);//结果如下:
			//键值Key = 9     实值Value = 139
			//键值Key = 11    实值Value = 16
			//键值Key = 13    实值Value = 36
			//键值Key = 15    实值Value = 46
	cout << endl;
	//③删除某个区间的所有元素---相当于清空
	m3.erase(m3.begin(),m3.end());
	printMap(m3);//结果:空
	cout << endl;

//查找
	m3 = m1;
	printMap(m3);//结果:空
	cout << endl;
	if (m3.find(6) != m3.end())
		cout << "找到了,m3[6] = " << m3[6] << endl;
	else
		cout << "没找到!" << endl;//√
	
	if (m3.find(12) != m3.end())
		cout << "找到了,m3[12] = " << m3[12] << endl;//√ m3[12] = 56
	else
		cout << "没找到!" << endl;



//统计---因为map容器中不能有重复的key值,所以结果只会是0或1
	int res = m3.count(13);
	cout << "Key值为13的元素个数为:" << res << endl;//1
	cout << "Key值为6的元素个数为:" << m3.count(8) << endl;//0

	system("pause");
	return 0;
}

3.9.6 map容器排序
①map容器默认排序规则为 :按照key值进行 从小到大排序
②利用仿函数自定义排序规则—在创建容器的时候就指明排序规则(按Key值降序)
③map容器中的value值是自定义数据类型Person类
④multimap容器—允许有Key值相同的元素

示例:

//(177-285)map容器:排序
/**/
//利用仿函数实现自定义排序规则---按照Key值降序排列
class MySort {
   
public:
	bool operator()(double a, double b)const {
   //加const
		if (a > b)
			return 1;
		else
			return 0;
	}
};
//打印map m
void printMap(map<double, double>& m) {
   
	for (map<double, double>::iterator it = m.begin(); it != m.end(); it++) {
   
		cout << "Key = " << it->first << ";\tValue = " << it->second << endl;
	}
}
//打印map m
void printMap(map<double, double,MySort>& m) {
   
	for (map<double, double,MySort>::iterator it = m.begin(); it != m.end(); it++) {
   
		cout << "Key = " << it->first << ";\tValue = " << it->second << endl;
	}
}
//打印map> m
void printMap(map<double, double, greater<>>& m) {
   
	for (map<double, double, greater<>>::iterator it = m.begin(); it != m.end(); it++) {
   
		cout << "Key = " << it->first << ";\tValue = " << it->second << endl;
	}
}
//自定义数据类型:
class Person {
   
public:
	string name;
	int age;
	int height;

	Person(string name, int age, int height) {
   
		this->name = name;
		this->age = age;
		this->height = height;
	}
};

//打印map m
void printMap(map<double, Person>& m) {
   
	for (map<double, Person>::iterator it = m.begin(); it != m.end(); it++) {
   
		cout << "Key = " << it->first << ";\t姓名:" << it->second.name
			<< "\t年龄:" << it->second.age << "\t身高:" << it->second.height << endl;
	}
}
//打印map m
void printMap(map<double, Person,MySort>& m) {
   
	for (map<double, Person, MySort>::iterator it = m.begin(); it != m.end(); it++) {
   
		cout << "Key = " << it->first << ";\t姓名:" << it->second.name
			<< "\t年龄:" << it->second.age << "\t身高:" << it->second.height << endl;
	}
}
//打印map> m
void printMap(map<double, Person, greater<>>& m) {
   
	for (map<double, Person, greater<>>::iterator it = m.begin(); it != m.end(); it++) {
   
		cout << "Key = " << it->first << ";\t姓名:" << it->second.name
			<< "\t年龄:" << it->second.age 

你可能感兴趣的:(c++,c++)