B站黑马c++学习笔记 —— 提高编程篇

大纲

1 模板

1.1 模板的概念

在这里插入图片描述

1.2 函数的模板

在这里插入图片描述

1.2.1 函数的模板语法

在这里插入图片描述

//函数模板
template<typename T>
void mySwap(T &a, T &b) {
    
    
	T temp = a;
	a = b;
	b = temp;
}
void test() {
    
    
	int a = 1;
	int b = 2;
	string c = "c";
	string d = "d";
	mySwap(a, b);
	//mySwap<int>(a, b); //显示指定类型
	mySwap(c, d);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;
	cout << "d = " << d << endl;
}

int main() {
    
    	
	test();
	return 0;
}

1.2.2 函数模板注意事项

在这里插入图片描述

1.2.3 函数模板案例

在这里插入图片描述

//排序

//交换模板
template<class T>
void mySwap(T &a, T &b) {
    
    
	T temp = a;
	a = b;
	b = temp;
}
//排序模板
template<class T>
void mySort(T arr,int len) {
    
    
	for (int i = 0; i < len; i++) {
    
    
		int max = i;
		for (int j = i + 1; j < len; j++) {
    
    
			if (arr[j] > arr[max]) {
    
    
				max = j;
			}
		}
		if (max != i) {
    
    
			mySwap(arr[max], arr[i]);
		}
	}
}
//打印模板
template<class T>
void myPrint(T arr,int len) {
    
    
	for (int i = 0; i < len; i++) {
    
    
		cout << arr[i] ;
	}
	cout << endl;
}
void test() {
    
    
	int arr1[] = {
    
     1,5,9,0,2,8,4 };
	char arr2[] = "asdwfg";
	int len1;
	int len2;
	len1 = sizeof(arr1) / sizeof(arr1[0]);
	len2 = sizeof(arr2) / sizeof(arr2[0]);
	mySort(arr1, len1);
	myPrint(arr1, len1);
	mySort(arr2,len2);
	myPrint(arr2, len2);
}

int main() {
    
    
	test();
	return 0;
}

1.2.4 普通函数与函数模板的区别

在这里插入图片描述

  • 建议使用显示指定类型的方式调用函数模板
//mySwap(a,b);
mySwap<int>(a, b);

1.2.5 普通函数与函数模板的调用规则

在这里插入图片描述

//强制调用函数模板
mySwap<>(a, b);

1.2.6 模板的局限性

//类定义
class person {
    
    
public:
	int m_age;
	string m_name;

	person(int age, string name) {
    
    
		this->m_age = age;
		this->m_name = name;
	}
};
//普通函数模板
template<class T>
bool myCompare(T &a, T &b) {
    
    
	if (a == b) {
    
    
		return true;
	}
	else {
    
    
		return false;
	}
}
//具体化模板
template<> bool myCompare(person &p1, person &p2) {
    
    
	if (p1.m_age == p2.m_age&&p1.m_name == p2.m_name) {
    
    
		return true;
	}
	else {
    
    
		return false;
	}
}
//打印
void myPrint(bool &ret) {
    
    
	if (ret) {
    
    
		cout << "相同" << endl;
	}
	else {
    
    
		cout << "不同" << endl;
	}
}
void test() {
    
    
	person p1 = {
    
     18,"Tom" };
	person p2 = {
    
     28,"Tom" };

	bool ret1 = myCompare(p1, p2);
	myPrint(ret1);
	bool ret2 = myCompare(p1.m_name, p2.m_name);
	myPrint(ret2);
}

int main() {
    
    
	test();
	return 0;
}

1.3 类模板

1.3.1 类模板语法

在这里插入图片描述

template<class nameType, class ageType>
class person{
    
    
public:
	nameType m_name;
	ageType m_age;
}

void test(){
    
    
	person<string,int> p1("Tom",18);
}

1.3.2 类模板与函数模板区别

在这里插入图片描述

template<class nameType, class ageType = int>
class person{
    
    
public:
	nameType m_name;
	ageType m_age;
}

void test(){
    
    
	person<string> p1("Tom",18);
}

1.3.3 类模板中成员函数创建时机

在这里插入图片描述

1.3.4 类模板对象做函数参数

在这里插入图片描述

//查看模板参数类型名
cout << typeid(T).name() << endl;
template<class T1, class T2>
class person {
    
    
public:
	T1 m_age;
	T2 m_name;

	person(T1 age, T2 name) {
    
    
		this->m_age = age;
		this->m_name = name;
	}

	void person_print() {
    
    
		cout << this->m_age << endl;
		cout << this->m_name << endl;
	}
};
//指定传入类型
void myPrint01(person<int, string> &p1) {
    
    
	p1.person_print();
}
void test01() {
    
    
	person<int, string> p1(18, "Tom");
	myPrint01(p1);
}
//参数模板化
template<class T1,class T2>
void myPrint02(person<T1, T2> &p2) {
    
    
	p2.person_print();
	cout << typeid(T1).name() << endl;
}
void test02() {
    
    
	person<int, string> p2(28, "Jack");
	myPrint02(p2);
}
//整个类模板化
template<class T>
void myPrint03(T &p3) {
    
    
	p3.person_print();
	cout << typeid(T).name() << endl;
}
void test03() {
    
    
	person<int, string> p3(38, "John");
	myPrint03(p3);
}

int main() {
    
    
	test01();
	test02();
	test03();
	return 0;
}

1.3.5 类模板与继承

在这里插入图片描述

//父类
template<class T>
class Base {
    
    
public:
	T m;
};
//子类
template<class T1,class T2>
class Son :public Base<T1> {
    
    
public:
	T2 n;
	Son() {
    
    
		cout << typeid(T1).name() << endl;
		cout << typeid(T2).name() << endl;
	}
};
void test() {
    
    
	Son<int, string> s1;
}

int main() {
    
    
	test();
	return 0;
}

1.3.6 类模板成员函数类外实现

template<class T1, class T2>
class person {
    
    
public:
	T1 m_age;
	T2 m_name;

	person(T1 age, T2 name);
	void person_print();
};
//构造函数的类外实现
template<class T1, class T2>
person<T1, T2>::person(T1 age, T2 name) {
    
    
	this->m_age = age;
	this->m_name = name;
}
//成员函数的类外实现
template<class T1, class T2>
void person<T1, T2>::person_print() {
    
    
	cout << this->m_age << endl;
	cout << this->m_name << endl;
}
void test() {
    
    
	person<int, string> p1(18,"Tom");
	p1.person_print();
}

int main() {
    
    
	test();
	return 0;
}

1.3.7 类模板分文件编写

在这里插入图片描述

  • tree.hpp
#pragma once
#include<iostream>
#include<string>

using namespace std;

template<class T1, class T2>
class tree {
    
    
public:
	T1 m_age;
	T2 m_name;

	tree(T1 age, T2 name);
	void tree_print();
};

//构造函数的类外实现
template<class T1, class T2>
tree<T1, T2>::tree(T1 age, T2 name) {
    
    
	this->m_age = age;
	this->m_name = name;
}
//成员函数的类外实现

template<class T1, class T2>
void tree<T1, T2>::tree_print() {
    
    
	cout << this->m_age << endl;
	cout << this->m_name << endl;
}
  • main.cpp
#include"tree.hpp"

void test() {
    
    
	tree<int, string> t1(180,"银杏");
	t1.tree_print();
}

int main() {
    
    
	test();
	return 0;
}

1.3.8 类模板与友元

在这里插入图片描述

template<class T1, class T2>
class person;
//提前声明全局函数
template<class T1, class T2>
void person_print2(person<T1, T2> p) {
    
    
	cout << " 类外实现 " << p.m_name << endl;
}

template<class T1, class T2>
class person {
    
    
	//全局函数类内实现
	friend void person_print1(person<T1,T2> p) {
    
    
		cout << " 类内实现 " << p.m_name << endl;
	}
	//全局函数类外实现
	friend void person_print2<>(person<T1, T2> p);
public:
	person(T1 age, T2 name) {
    
    
		this->m_age = age;
		this->m_name = name;
	}
private:
	T1 m_age;
	T2 m_name;
};

void test() {
    
    
	//类内
	person<int, string> p1(18,"Tom");
	person_print1(p1);
	//类外
	person<int, string> p2(28, "Rose");
	person_print2(p2);
}

int main() {
    
    
	test();
	return 0;
}

1.3.9 类模板案例 — 通用数组

在这里插入图片描述

  • main.cpp
class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
};

void printArray(myArray<person> & arr) {
    
    
	for (int i = 0; i < arr.get_size(); i++) {
    
    
		cout << arr[i].m_name << "\n" << arr[i].m_age << endl;
	}
}

void test() {
    
    
	myArray<person> arr1(3);
	person p1("A", 18);
	person p2("B", 28);
	person p3("C", 38);

	arr1.push_back(p1);
	arr1.push_back(p2);
	arr1.push_back(p3);

	printArray(arr1);
}

int main() {
    
    
	test();
	return 0;
}
  • myArray.hpp
#pragma once
#include<iostream>
#include<string>
using namespace std;

template<class T>
class myArray {
    
    
public:
	myArray(int capacity) {
    
    
		//cout << "有参构造" << endl;
		this->m_Capacity = capacity;
		this->m_size = 0;
		this->pAddress = new T[this->m_Capacity];
	}

	myArray(const myArray & arr) {
    
    
		//cout << "拷贝构造" << endl;
		this->m_Capacity = arr.m_Capacity;
		this->m_size = arr.m_size;
		//this->pAddress = arr.pAddress; //浅拷贝 堆区数据会重复释放
		this->pAddress = new T[arr.m_Capacity];	//深拷贝
		for (int i = 0; i < this->m_size; i++) {
    
    
			this->pAddress[i] = arr.pAddress[i];
		}
	}

	myArray & operator=(const myArray & arr) {
    
    
		//cout << "operator=构造" << endl;
		if (this->pAddress != NULL) {
    
    
			delete[] this->pAddress;
			this->pAddress = NULL;
			this->m_Capacity = 0;
			this->m_size = 0;
		}
		this->m_Capacity = arr.m_Capacity;
		this->m_size = arr.m_size;
		this->pAddress = new T[arr.m_Capacity];
		for (int i = 0; i < this->m_size; i++) {
    
    
			this->pAddress[i] = arr.pAddress[i];
		}
		return *this;
	}
	//尾插法
	void push_back(const T & val) {
    
    
		//判断是否有容量
		if (this->m_size == this->m_Capacity) {
    
    
			return;
		}
		//插入数据
		this->pAddress[this->m_size] = val;
		//更新数组大小
		this->m_size++;
	}
	//尾删法
	void pop_back() {
    
    
		//判断是否有数据
		if (this->m_size == 0) {
    
    
			return;
		}
		//让用户访问不到该元素,逻辑删除
		this->m_size--;
	}
	//下标访问数据
	T& operator[](int index) {
    
    
		return this->pAddress[index];
	}
	//获取数组容量
	int get_Capacity() {
    
    
		return this->m_Capacity;
	}
	//获取数组大小
	int get_size() {
    
    
		return this->m_size;
	}

	~myArray() {
    
    
		//cout << "析构函数" << endl;
		if (this->pAddress != NULL) {
    
    
			delete[] this->pAddress;
			this->pAddress = NULL;
		}
	}
private:
	//堆区数组指针
	T * pAddress;
	//数组容量
	int m_Capacity;
	//数组大小
	int m_size;
};

2 STL初识

2.1 STL的诞生

在这里插入图片描述

2.2 STL基本概念

在这里插入图片描述

2.3 STL六大组件

在这里插入图片描述

2.4 STL中容器、算法、迭代器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.5 容器、算法、迭代器初识

2.5.1 vector存放内置数据类型

在这里插入图片描述

#include<vector>
#include<algorithm> //标准算法头文件

void myPrint(int val) {
    
    
	cout << val << endl;
}

void test() {
    
    
	vector<int> v1;
	//尾插数据
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	//第一种遍历
	vector<int>::iterator itBegin = v1.begin();	//起始迭代器 指向容器中第一个元素
	vector<int>::iterator itEnd = v1.end();		//结束迭代器 指向容器中最后一个元素的下一个位置
	while (itBegin != itEnd) {
    
    
		myPrint(*itBegin);
		itBegin++;
	}
	//第二种遍历
	for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
    
    
		myPrint(*it);
	}
	//第三种遍历 利用STL提供的遍历算法
	for_each(v1.begin(), v1.end(), myPrint);
}

int main() {
    
    
	test();
	return 0;
}

2.5.2 vector存放自定义数据类型

在这里插入图片描述

#include<vector>

class person {
    
    
public:
	string m_name;
	int m_age;

	person(string name,int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
};

void myPrint(person &p) {
    
    
	cout << p.m_name << "\t" << p.m_age << endl;
}

void test() {
    
    
	//自定义数据类型
	vector<person> p;
	person p1("张三", 18);
	person p2("李四", 28);
	person p3("王五", 38);

	p.push_back(p1);
	p.push_back(p2);
	p.push_back(p3);

	for (vector<person>::iterator it1 = p.begin(); it1 != p.end(); it1++) {
    
    
		myPrint(*it1);
		//cout << it1->m_name << "\t" << it1->m_age << endl;
	}
	
	//自定义数据指针
	vector<person*> v;
	person p4("张三", 19);
	person p5("李四", 29);
	person p6("王五", 39);

	v.push_back(&p4);
	v.push_back(&p5);
	v.push_back(&p6);

	for (vector<person*>::iterator it2 = v.begin(); it2 != v.end(); it2++) {
    
    
		myPrint(**it2);
		//cout << (*it2)->m_name << "\t" << (*it2)->m_age << endl;
	}
}

int main() {
    
    
	test();
	return 0;
}

2.5.3 vector容器嵌套容器

在这里插入图片描述

#include<vector>

void test() {
    
    
	vector<vector<int>> v;
	vector<int> v1;
	vector<int> v2;
	vector<int> v3;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i);
		v2.push_back(i * 10 + 1);
		v3.push_back((i + 2) * 7);
	}
	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);

	for (vector<vector<int>>::iterator it1 = v.begin(); it1 != v.end(); it1++) {
    
    
		//(*it1) -- 容器 vector<int>
		for (vector<int>::iterator it2 = (*it1).begin(); (it2) != (*it1).end(); it2++) {
    
    
			cout << *it2 << "\t";
		}
		cout << endl;
	}
}

int main() {
    
    
	test();
	return 0;
}

3 STL-常用容器

3.1 string容器

3.1.1 string基本概念

在这里插入图片描述

3.1.2 string构造函数

在这里插入图片描述

void test() {
    
    
	//string()
	string s1;
	//string(const char* s)
	const char* str = "hello world";
	string s2(str);
	//string(const string& str)
	string s3(s2);
	//string(int n,char c)
	string s4(5, 'a');

	cout << s1 << endl
		<< s2 << endl
		<< s3 << endl
		<< s4 << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.1.3 string赋值操作

在这里插入图片描述

void test() {
    
    
	string str1;
	str1.assign("hello world");
	cout << str1 << endl;

	//把前n个字符赋值
	string str2;
	str2.assign("hello world", 8);
	cout << str2 << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.1.4 string字符串拼接

在这里插入图片描述

void test() {
    
    
	string str1 = "~$root:";
	str1 += "zxy";
	cout << str1 << endl;

	string str2 = ":";
	str1 += str2;
	cout << str1 << endl;
	//截取字符串的前 n 个添加
	str1.append("sudo apt-get install ros-kinetic-moveit",10);
	cout << str1 << endl;
	//截取字符串的第 m 到第 n 个添加
	string str3 = "sudo apt-get install ros-kinetic-moveit";
	str1.append(str3, 10,-1);
	cout << str1 << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.1.5 string查找与替换

在这里插入图片描述

void test() {
    
    
	string str = "abcdab";
	//如果找到 返回字符串首位置,未找到返回值-1
	int pos;
	//find	从左往右第一次出现的位置
	pos = str.find("ab");
	cout << "find : " << pos << endl;
	//rfind	从右往左第一次出现的位置
	pos = str.rfind("ab");
	cout << "rfind: " << pos << endl;
	//str.replace(替换的起始位置<从0开始>, 替换的个数, 替换后的内容);
	string str2 = " ab ** ab ";
	str.replace(2, 2, str2);
	cout << str << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.1.6 string字符串比较

在这里插入图片描述

string str1 = "abc";
string str2 = "bbc";
int ret = str1.compare(str2);

3.1.7 string字符存取

在这里插入图片描述

void test() {
    
    
	string str1 = "abcdefg";

	//通过[]、at访问单个字符
	for (int i = 0; i < str1.size(); i++) {
    
    
		cout << str1[i] ;
		cout << str1.at(i) ;
	}

	//通过[]、at修改单个字符
	for (int i = 0; i < str1.size(); i++) {
    
    
		//str1[i] = 'x';
		str1.at(i) = 'x';
	}
	cout << str1 << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.1.8 string插入与删除

在这里插入图片描述

void test() {
    
    
	string str1 = "abcde";
	string str2 = "123";

	//从第2号位置插入字符串str2<插入字符串后的首位置为2>
	str1.insert(2, str2);
	cout << str1 << endl;

	//删除第2号位置起的3个字符
	str1.erase(2, 3);
	cout << str1 << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.1.9 string子串

在这里插入图片描述

void test() {
    
    
	string email = "[email protected]";
	
	int pos = email.find('@');
	
	//从第0号位置开始,截取pos个字符
	string sub_name = email.substr(0, pos);
	cout << sub_name << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.2 vector容器

3.2.1 vector基本概念

在这里插入图片描述
在这里插入图片描述

3.2.2 vector构造函数

在这里插入图片描述

#include<vector>

void printVector(vector<int> &v) {
    
    
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    
    
		cout << *it << " " ;
	}
	cout << endl;
}

void test() {
    
    
	//默认无参构造
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i * 6 + 8);
	}
	printVector(v1);
	//通过区间构造
	vector<int> v2(v1.begin(), v1.end());
	printVector(v2);
	//通过 n 个 elem 构造(元素个数,元素值)
	vector<int> v3(10,100);
	printVector(v3);
	//通过拷贝构造
	vector<int> v4(v3);
	printVector(v4);
}

int main() {
    
    
	test();
	return 0;
}

3.2.3 vector赋值操作

在这里插入图片描述

	vector<int> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i * 6 + 8);
	}


	vector<int> v2;
	v2 = v1;
	
	vector<int> v3;
	v3.assign(v1.begin(), v1.end());

	vector<int> v4;
	v4.assign(10,100);

3.2.4 vector容量和大小

在这里插入图片描述

#include<vector>

void printVector(vector<int> &v) {
    
    
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    
    
		cout << *it << " " ;
	}
	cout << endl;
	cout << "v1的容量为: " << v.capacity() << endl;
	cout << "v1的大小为: " << v.size() << endl;
}

void test() {
    
    
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i * 9 + 8);
	}
	//判断是否为空
	if (v1.empty()) {
    
    
		cout << "v1 is empty" << endl;
	}
	else {
    
    
		printVector(v1);
		//重新指定容器大小,(容器大小,填充值(默认为0))
		v1.resize(15,100);
		printVector(v1);
		v1.resize(5);
		printVector(v1);
	}
}

int main() {
    
    
	test();
	return 0;
}

3.2.5 vector插入与删除

在这里插入图片描述

#include<vector>

void printVector(vector<int> &v) {
    
    
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    
    
		cout << *it << " ";
	}
	cout << endl;
}

void test() {
    
    
	vector<int> v1;
	//尾插
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i * 8 + 8);
	}
	printVector(v1);
	//尾删
	v1.pop_back();
	printVector(v1);
	//insert(位置迭代器,插入个数(默认1个),插入值)
	v1.insert(v1.begin() + 1, 2, 99);
	printVector(v1);
	//删除
	v1.erase(v1.begin() + 2);
	printVector(v1);
	//清空
	v1.clear();
	printVector(v1);
}

int main() {
    
    
	test();
	return 0;
}

3.2.6 vector数据存取

在这里插入图片描述

#include<vector>

void test() {
    
    
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i * 11 + 45);
	}
	//利用[]访问数组元素
	for (int i = 0; i < v1.size(); i++) {
    
    
		cout << v1[i] << " ";
	}
	cout << endl;
	//利用at访问数组元素
	for (int i = 0; i < v1.size(); i++) {
    
    
		cout << v1.at(i) << " ";
	}
	cout << endl;
	//获取第一个元素
	cout << "第一个元素  : " << v1.front() << endl;
	//获取最后一个元素
	cout << "最后一个元素: " << v1.back() << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.2.7 vector互换容器

在这里插入图片描述

#include<vector>

void printVector(vector<int> &v,string index) {
    
    
	cout << index << ": ";
	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    
    
		cout << *it << " " ;
	}
	cout << endl;
}

void test() {
    
    
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i * 13 + 24);
	}
	printVector(v1,"v1");
	vector<int> v2;
	for (int i = 0; i < 10; i++) {
    
    
		v2.push_back(i * 56 + 2);
	}
	printVector(v2, "v2");
	//容器元素互换
	v1.swap(v2);
	printVector(v1, "v1");
	printVector(v2, "v2");
	
	//收缩内存
	vector<int> v3;
	for (int i = 0; i < 1000; i++) {
    
    
		v3.push_back(i * 13 + 24);
	}
	cout << "v3的容量为: " << v3.capacity() << endl;
	cout << "v3的大小为: " << v3.size() << endl;
	v3.resize(10);
	cout << "v3的容量为: " << v3.capacity() << endl;
	cout << "v3的大小为: " << v3.size() << endl;
	//vector<int>(v3)为匿名对象,系统自动回收
	vector<int>(v3).swap(v3);
	cout << "v3的容量为: " << v3.capacity() << endl;
	cout << "v3的大小为: " << v3.size() << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.2.8 vector预留空间

在这里插入图片描述

#include<vector>

void test() {
    
    
	vector<int> v1;
	int num = 0;
	int * p = NULL;
	for (int i = 0; i < 1000; i++) {
    
    
		v1.push_back(i);
		//如果重新开辟了记一次
		if (p != &v1[0]) {
    
    
			p = &v1[0];
			num++;
		}
	}
	cout << "v1开辟内存空间次数: " << num << endl;

	vector<int> v2;
	v2.reserve(1000);
	int re_num = 0;
	int * re_p = NULL;
	for (int i = 0; i < 1000; i++) {
    
    
		v2.push_back(i);
		//如果重新开辟了记一次
		if (re_p != &v2[0]) {
    
    
			re_p = &v2[0];
			re_num++;
		}
	}
	cout << "v2开辟内存空间次数: " << re_num << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.3 deque容器

3.3.1 deque容器基本概念

在这里插入图片描述
在这里插入图片描述

3.3.2 deque构造函数

在这里插入图片描述

#include<deque>

void printDeque(const deque<int>& d) {
    
    
	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
    
    
		//*it = 100;	//常量需要使用const_iterator
		cout << *it << " ";
	}
	cout << endl;
}

void test() {
    
    
	deque<int> d1;
	for (int i = 0; i < 10; i++) {
    
    
		d1.push_back(i * 11);
		d1.push_front(i * 10);
	}
	printDeque(d1);

	deque<int> d2(d1.begin() + 1, d1.end()-1);
	printDeque(d2);

	deque<int> d3(20,99);
	printDeque(d3);

	deque<int> d4(d3);
	printDeque(d4);
}

int main() {
    
    
	test();
	return 0;
}

3.3.3 deque赋值操作

在这里插入图片描述

3.3.4 deque大小操作

在这里插入图片描述

3.3.5 deque插入与删除

在这里插入图片描述

	deque<int> d1;
	deque<int> d2;
	//在指定位置插入区间值
	d1.insert(d1.begin(),d2.begin(),d2.end())

3.3.6 deque数据存取

在这里插入图片描述

3.3.7 deque排序

在这里插入图片描述

#include<deque>
#include<algorithm>

void printDeque(const deque<int>& d) {
    
    
	for (int i = 0; i < d.size(); i++) {
    
    
		cout << d[i] << " ";
	}
	cout << endl;
}

void test() {
    
    
	deque<int> d1;
	for (int i = 0; i < 10; i++) {
    
    
		d1.push_back(i * 11);
		d1.push_front(i * 10);
	}
	printDeque(d1);
	//默认由小到大排序
	//支持随机访问的迭代器的容器,都可以利用sort进行排序
	sort(d1.begin(), d1.end());
	printDeque(d1);
}

int main() {
    
    
	test();
	return 0;
}

3.4 案例 – 评委打分

3.4.1 案例描述

在这里插入图片描述

3.4.2 实现步骤

在这里插入图片描述

3.4.3 案例实现

#include<vector>
#include<algorithm>
#include<deque>
#include<ctime>

class player {
    
    
public:
	int m_id;			//编号
	int m_score;		//平均分
	deque<int> score;	//所有评分

	player(int m_id,int m_score){
    
    
		this->m_id = m_id;
		this->m_score = m_score;
	}
	void printScore() {
    
    
		for (int i = 0; i < 10; i++) {
    
    
			cout << this->score[i] << " ";
		}
		cout << endl;
	}
};

void pushPlayer(vector<player> &play) {
    
    
	for (int i = 0; i < 5; i++) {
    
    
		player p(i + 1, 0);
		play.push_back(p);
	}
}

void test() {
    
    
	vector<player> play;
	play.reserve(5);
	//选手参加
	pushPlayer(play);

	srand((unsigned int)time(NULL));
	for (vector<player>::iterator it = play.begin(); it != play.end(); it++) {
    
    
		for (int i = 0; i < 10; i++) {
    
    
			//打分
			//rand() % 41 为0 ~ 40
			int score_rand = rand() % 41 + 60;
			it->score.push_back(score_rand);
		}
		//对成绩进行排序
		sort(it->score.begin(), it->score.end());
		it->printScore();
		//去掉最高分和最低分
		it->score.pop_back();
		it->score.pop_front();
		//求平均分
		int sum = 0;
		for (int i = 0; i < it->score.size(); i++) {
    
    
			sum += it->score[i];
		}
		int avg = sum / it->score.size();
		it->m_score = avg;
		cout << "id: " << it->m_id << " 成绩为: " << it->m_score << endl << endl;
	}
}

int main() {
    
    
	test();
	return 0;
}

3.5 stack容器

3.5.1 stack基本概念

在这里插入图片描述
在这里插入图片描述

  • 栈不允许有遍历行为
  • 栈可以判断容器是否为空 empty()
  • 栈可以返回元素个数 size()

3.5.2 stack常用接口

在这里插入图片描述

#include<stack>

void test() {
    
    
	stack<int> s;
	for (int i = 0; i < 5; i++) {
    
    
		s.push(i * 4 + 1);
	}
	cout << "出栈前栈的大小: " << s.size() << endl;
	while (!s.empty()) {
    
    
		//查看栈顶元素
		cout << s.top() << endl;
		//出栈
		s.pop();
	}
	cout << "出栈后栈的大小: " << s.size() << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.6 queue容器

3.6.1 queue基本概念

在这里插入图片描述

  • 队列不允许有遍历行为
  • 队列可以判断容器是否为空 empty()
  • 队列可以返回元素个数 size()

3.6.2 queue常用接口

在这里插入图片描述

#include<queue>

void test() {
    
    
	queue<int> q;
	for (int i = 0; i < 5; i++) {
    
    
		q.push(i * 7 + 2);
	}
	while (!q.empty()) {
    
    
		cout << "队列的队头: " << q.front() << endl;
		cout << "队列的队尾: " << q.back() << endl;
		q.pop();
	}
	cout << "" << q.size() << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.7 list容器

3.7.1 list基本概念

在这里插入图片描述
在这里插入图片描述

  • 链表可以在任意位置进行快速的插入或删除元素
  • 链表动态分配存储,不会造成内存浪费
  • 链表遍历速度慢
  • 链表占用空间大
    在这里插入图片描述
  • List链表中,插入和删除元素不会造成原有list迭代器的失效,而vector是不成立的(内存满了之后另开一处空间进行存储)

3.7.2 list构造函数

在这里插入图片描述

#include<list>

void printList(const list<int> &L) {
    
    
	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
    
    
		cout << *it << " ";
	}
	cout << endl;
}

void test() {
    
    
	//默认构造
	list<int> L1;
	for (int i = 0; i < 10; i++) {
    
    
		L1.push_back(i * 2 + 3);
	}
	printList(L1);
	//区间构造
	list<int> L2(L1.begin(), L1.end());
	printList(L2);
	//拷贝构造
	list<int> L3(L2);
	printList(L3);
}

int main() {
    
    
	test();
	return 0;
}

3.7.3 list赋值与交换

在这里插入图片描述

3.7.4 list大小操作

在这里插入图片描述

3.7.5 list插入与删除

在这里插入图片描述

#include<list>

void printList(const list<int> &L) {
    
    
	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
    
    
		cout << *it << " ";
	}
	cout << endl;
}

void test() {
    
    
	list<int> L1;
	for (int i = 0; i < 10; i++) {
    
    
		L1.push_back(i % 2 );
	}
	printList(L1);
	//insert插入
	L1.insert(++L1.begin(), 2, 3);
	printList(L1);
	//erase删除
	L1.erase(++L1.begin());
	printList(L1);
	//remove删除,删除容器中所有指定的元素值
	L1.remove(0);
	printList(L1);
}

int main() {
    
    
	test();
	return 0;
}

3.7.6 list数据存取

在这里插入图片描述

3.7.7 list反转与排序

在这里插入图片描述

#include<list>

void printList(const list<int> &L) {
    
    
	for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
    
    
		cout << *it << " ";
	}
	cout << endl;
}

//排序的判断函数
bool myCompare(int v1, int v2) {
    
    
	return v1 > v2;
}

void test() {
    
    
	list<int> L1;
	for (int i = 0; i < 10; i++) {
    
    
		L1.push_back((i % 2) * 6 + i);
	}
	printList(L1);

	L1.reverse();
	cout << "反转后的链表: " << endl;
	printList(L1);

	L1.sort();//默认升序
	cout << "排序后的链表: " << endl;
	printList(L1);

	//降序排列操作
	L1.sort(myCompare);
	printList(L1);

	//所有不支持随机访问迭代器的容器,不可以用标准算法(eg:sort())(全局函数)
	//不支持随机访问迭代器的容器,内部会提供对应的算法(成员函数)
}

int main() {
    
    
	test();
	return 0;
}

3.7.8 list排序案例

在这里插入图片描述

#include<list>
#include<ctime>

class person {
    
    
public:
	string m_name;
	int m_age;
	int m_height;
	person() {
    
    };
	person(string name, int age,int height) {
    
    
		this->m_name = name;
		this->m_age = age;
		this->m_height = height;
	}
};
//创建对象
void creatPerson(list<person> &L,int num) {
    
    
	string nameSeed = "ABCDEFGHIJK";
	for (int i = 0; i < num; i++) {
    
    
		person p;
		p.m_name += nameSeed[i];
		p.m_age = 20 + rand() % 5;
		p.m_height = 180 + rand() % 10;

		L.push_back(p);
	}
}
//打印信息
void printList(const list<person> &L) {
    
    
	for (list<person>::const_iterator it = L.begin(); it != L.end(); it++) {
    
    
		cout << "姓名: " << (*it).m_name << " 年龄: " << (*it).m_age << " 身高: " << (*it).m_height << endl;
	}
}
//排序规则
bool myCompare(person &p1,person &p2) {
    
    
	//如果年龄不同,进行升序排列
	if (p1.m_age != p2.m_age) {
    
    
		return p1.m_age < p2.m_age;
	}
	//如果年龄相同,对身高进行降序排列
	else {
    
    
		return p1.m_height > p2.m_height;
	}
}

void test() {
    
    
	srand((unsigned int)time(NULL));

	list<person> L1;
	creatPerson(L1, 10);

	cout << "排序前:" << endl;
	printList(L1);

	cout << "排序后:" << endl;
	L1.sort(myCompare);
	printList(L1);
}

int main() {
    
    
	test();
	return 0;
}

3.8 set/multiset容器

3.8.1 set基本概念

在这里插入图片描述

3.8.2 set构造和赋值

在这里插入图片描述

#include<set>
#include<ctime>

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

void test() {
    
    
	srand((unsigned)time(NULL));
	set<int> s1;
	for (int i = 0; i < 20; i++) {
    
    
		//插入数据只能用insert
		s1.insert(rand() % 10);
	}
	//set容器不允许重复的值插入
	printSet(s1);
	
	multiset<int> s2;
	for (int i = 0; i < 20; i++) {
    
    
		s2.insert(rand() % 10);
	}
	//multiset容器允许重复的值插入
	printSet(s2);
}

int main() {
    
    
	test();
	return 0;
}

3.8.3 set大小和交换

在这里插入图片描述

3.8.4 set插入与删除

在这里插入图片描述

3.8.5 set查找和统计

在这里插入图片描述

#include<set>
#include<ctime>

void test() {
    
    
	srand((unsigned)time(NULL));

	set<int> s1;
	for (int i = 0; i < 20; i++) {
    
    
		s1.insert(rand() % 10);
	}
	//找到元素返回其迭代器位置,没找到返回set.end()位置
	set<int>::iterator pos = s1.find(5);
	if (pos != s1.end()) {
    
    
		cout << "找到了" << endl;
	}
	else {
    
    
		cout << "没有找到" << endl;
	}

	multiset<int> s2;
	for (int i = 0; i < 20; i++) {
    
    
		s2.insert(rand() % 10);
	}
	//返回元素的个数
	//对于set而言结果只有0或1
	int num = s2.count(5);
	cout << "元素个数为: " << num << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.8.6 set和multiset区别

在这里插入图片描述

#include<set>
#include<ctime>

void test() {
    
    
	srand((unsigned)time(NULL));

	set<int> s1;
	for (int i = 0; i < 10; i++) {
    
    
		pair<set<int>::iterator, bool> ret = s1.insert(rand() % 10);
		if (ret.second) {
    
    
			cout << "数据插入成功  " << *ret.first << endl;
		}
		else {
    
    
			cout << "数据插入失败  " << *ret.first << endl;
		}
	}

	multiset<int> s2;
	for (int i = 0; i < 20; i++) {
    
    
		s2.insert(rand() % 10);
	}
}

int main() {
    
    
	test();
	return 0;
}

3.8.7 pair对组创建

在这里插入图片描述

void test() {
    
    
	//第一种
	pair<int, string> p1(1, "a");
	cout << p1.first << " " << p1.second << endl;
	//第二种
	pair<int, string> p2 = make_pair(2, "b");
	cout << p2.first << " " << p2.second << endl;
}

int main() {
    
    
	test();
	return 0;
}

3.8.8 set容器排序

在这里插入图片描述

#include<set>

class person {
    
    
public:
	string m_name;
	int m_age;
	int m_height;
	person() {
    
    };
	person(string name, int age, int height) {
    
    
		this->m_name = name;
		this->m_age = age;
		this->m_height = height;
	}
};

//仿函数建立排序规则
class myCompare1 {
    
    
public:
	bool operator()(int v1, int v2) {
    
    
		return v1 > v2;
	}
};
class myCompare2 {
    
    
public:
	bool operator()(const person &p1, const person &p2) {
    
    
		if (p1.m_age == p2.m_age) {
    
    
			return p1.m_height > p2.m_height;
		}
		else {
    
    
			return p1.m_age > p2.m_age;
		}
	}
};
//创建对象
void creatPerson(int num, set<person, myCompare2> &s) {
    
    
	string nameSeed = "ABCDEFGHIJKLMN";
	for (int i = 0; i < num; i++) {
    
    
		person p;
		p.m_name += nameSeed[i];
		p.m_age = 20 + rand() % 10;
		p.m_height = 170 + rand() % 10;
		s.insert(p);
	}
}
//打印信息
void printSet(set<person, myCompare2> &s) {
    
    
	for (set<person, myCompare2>::iterator it = s.begin(); it != s.end(); it++) {
    
    
		cout << " 姓名: " << (*it).m_name << " 年龄: " << (*it).m_age << " 身高: " << (*it).m_height << endl;
	}
}

void test() {
    
    
	//内置数据类型
	//排序规则在插入数据之前
	set<int, myCompare1> s1;
	for (int i = 0; i < 20; i++) {
    
    
		s1.insert(rand() % 10);
	}
	for (set<int, myCompare1>::iterator it = s1.begin(); it != s1.end(); it++) {
    
    
		cout << *it << " ";
	}
	cout << endl;

	//自定义数据类型
	set<person, myCompare2> s2;
	creatPerson(9, s2);
	printSet(s2);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

3.9 map/multimap容器

3.9.1 map基本概念

在这里插入图片描述

3.9.2 map构造和赋值

在这里插入图片描述

#include<map>

void printMap(const map<int, int> &m) {
    
    
	for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++) {
    
    
		cout << it->first << "\t" << it->second << endl;
	}
}

void test() {
    
    
	map<int, int> m1;
	for (int i = 0; i < 10; i++) {
    
    
		//插入元素要使用对组pair
		m1.insert(pair<int, int>(i, rand() % 41 + 60));
	}
	printMap(m1);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

3.9.3 map大小和交换

在这里插入图片描述

3.9.4 map插入与删除

在这里插入图片描述

#include<map>

void printMap(const map<int, int> &m) {
    
    
	for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++) {
    
    
		cout << it->first << "\t" << it->second << endl;
	}
}

void test() {
    
    
	map<int, int> m1;
	//第一种
	m1.insert(pair<int, int>(5, 10));
	//第二种
	m1.insert(make_pair(4, 20));
	//第三种
	m1.insert(map<int, int>::value_type(3, 30));
	//第四种 不建议用于插入数据 可以用于读取value值
	//m1[2] = 40;
	//cout << m1[3] << endl;
	printMap(m1);

	m1.erase(m1.begin());
	printMap(m1);
	//根据key值进行删除
	m1.erase(4);
	printMap(m1);

	m1.erase(m1.begin(),m1.end());
	printMap(m1);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

3.9.5 map查找和统计

在这里插入图片描述

3.9.6 map容器排序

在这里插入图片描述

#include<map>

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

void printMap(const map<int, int, mapCompare> &m) {
    
    
	for (map<int, int, mapCompare>::const_iterator it = m.begin(); it != m.end(); it++) {
    
    
		cout << it->first << "\t" << it->second << endl;
	}
}

void test() {
    
    
	map<int, int, mapCompare> m1;
	for (int i = 0; i < 10; i++) {
    
    
		m1.insert(make_pair(i, rand() % 41 + 60));
	}
	printMap(m1);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

3.10 案例 – 员工分组

3.10.1 案例描述

在这里插入图片描述

3.10.2 实现步骤

在这里插入图片描述

3.10.3 案例实现

#include<vector>
#include<map>
#include<ctime>
#define CEHUA 0
#define MEISHU 1
#define YANFA 2

class stuff {
    
    
public:
	string m_name;
	int m_salary;
	stuff() {
    
    };
	stuff(string name, int salary) {
    
    
		this->m_name = name;
		this->m_salary = salary;
	}
};
//员工信息填入
void creatStuff(vector<stuff> &v) {
    
    
	string nameSeed = "ABCDEFGHIJ";
	for (int i = 0; i < 10; i++) {
    
    
		stuff s;
		s.m_name += nameSeed[i];
		s.m_salary = 5000 + (rand() % 10) * 500;
		v.push_back(s);
	}
}
//打印员工信息
void printStuff(const multimap<int, stuff> &m) {
    
    
		cout << "------------------------" << endl;
		cout << "策划部门:" << endl;
		multimap<int, stuff>::const_iterator pos = m.find(CEHUA);//策划第一个人位置
		int num = m.count(CEHUA);//策划组人数
		int index = 0;
		for (; pos != m.end() && index < num; pos++, index++) {
    
    
				cout << "姓名:" << pos->second.m_name << "   工资:" << pos->second.m_salary << endl;
		}

		cout << "------------------------" << endl;
		cout << "美术部门:" << endl;
		pos = m.find(MEISHU);
		num = m.count(MEISHU);
		index = 0;
		for (; pos != m.end() && index < num; pos++, index++) {
    
    
			cout << "姓名:" << pos->second.m_name << "   工资:" << pos->second.m_salary << endl;
		}

		cout << "------------------------" << endl;
		cout << "研发部门:" << endl;
		pos = m.find(YANFA);
		num = m.count(YANFA);
		index = 0;
		for (; pos != m.end() && index < num; pos++, index++) {
    
    
			cout << "姓名:" << pos->second.m_name << "   工资:" << pos->second.m_salary << endl;
		}
}
//分配部门
void allocateDepart(const vector<stuff> &v, multimap<int, stuff> &m) {
    
    

	for (vector<stuff>::const_iterator it = v.begin(); it != v.end(); it++) {
    
    
		m.insert(make_pair(rand() % 3 , *it));
	}
}

void test() {
    
    
	//招聘员工
	vector<stuff> v;
	creatStuff(v);

	//部门分配
	multimap<int, stuff> m;
	allocateDepart(v,m);

	//打印信息
	printStuff(m);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

4 STL-函数对象

4.1 函数对象

4.1.1 函数对象概念

在这里插入图片描述

4.1.2 函数对象使用

在这里插入图片描述

class myPrint {
    
    
public:
	//函数对象相较于普通函数,可以有自己的状态,可以统计次数等
	int count;
	myPrint() {
    
    
		this->count = 0;
	}
	void operator()(string text) {
    
    
		cout << text << endl;
		count++;
	}
};
//函数对象可以作为参数传递
void print_test(myPrint &mP, string text) {
    
    
	for (int i = 0; i < 5; i++) {
    
    
		mP(text);
	}
	cout << mP.count << endl;
}

void test() {
    
    
	//函数对象创建
	myPrint mP;
	string text = "hello world";
	print_test(mP, text);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

4.2 谓词

4.2.1 谓词概念

在这里插入图片描述

  • 谓词体现在返回类型,元数 体现在参数个数

4.2.1 一元谓词

#include<vector>
#include<algorithm>

class score {
    
    
public:
	bool operator()(int value) {
    
    
		return value > 90;
	}
};

void test() {
    
    
	vector<int> v;
	for (int i = 0; i < 10; i++) {
    
    
		v.push_back(60 + rand() % 41);
	}
	//score()匿名函数对象
	vector<int>::iterator pos = find_if(v.begin(), v.end(), score());
	if (pos == v.end()) {
    
    
		cout << "failed" << endl;
	}
	else {
    
    
		cout << *pos << endl;
	}
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

4.2.1 二元谓词

#include<vector>
#include<algorithm>

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

void printVector(vector<int> &v) {
    
    
	for (vector<int>::iterator pos = v.begin(); pos != v.end(); pos++) {
    
    
		cout << *pos << " ";
	}
	cout << endl;
}

void test() {
    
    
	vector<int> v;
	for (int i = 0; i < 10; i++) {
    
    
		v.push_back(60 + rand() % 41);
	}

	cout << "修改规则前:" << endl;
	sort(v.begin(), v.end());
	printVector(v);

	cout << "修改规则后: " << endl;
	sort(v.begin(), v.end(), sortRules());
	printVector(v);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();	return 0;
}

4.3 内建函数对象

4.3.1 内建函数对象意义

在这里插入图片描述

4.3.2 算术仿函数

在这里插入图片描述

#include<functional>

void test() {
    
    
	//取反仿函数
	negate<int> n;
	cout << n(10) << endl;

	//取模仿函数
	//二元仿函数也只定义一个数据类型,默认两个相同
	modulus<int> m;
	cout << m(50, 7) << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

4.3.3 关系仿函数

在这里插入图片描述

#include<functional>
#include<vector>
#include<algorithm>

void test() {
    
    
	vector<int> v;
	for (int i = 0; i < 10; i++) {
    
    
		v.push_back(60 + rand() % 41);
	}
	//greater<int>() 内建大于函数的匿名函数对象
	sort(v.begin(), v.end(), greater<int>());
	for (vector<int>::iterator pos = v.begin(); pos != v.end(); pos++) {
    
    
		cout << *pos << " ";
	}
	cout << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

4.3.4 逻辑仿函数

在这里插入图片描述

#include<functional>
#include<vector>
#include<algorithm>

void test() {
    
    
	vector<bool> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(rand() % 2);
	}

	vector<bool> v2;
	v2.resize(v1.size());
	//将容器v1的值搬运到v2 搬运前必须指定目标容器的大小 即:v2.resize(v1.size());
	transform(v1.begin(), v1.end(), v2.begin(), logical_not<bool>());

	for (vector<bool>::iterator pos = v2.begin(); pos != v2.end(); pos++) {
    
    
		cout << *pos << " ";
	}
	cout << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5 STL-常用算法

在这里插入图片描述

5.1 常用遍历算法

在这里插入图片描述

5.1.1 for_each

在这里插入图片描述

#include<vector>
#include<algorithm>

void printVector1(int val) {
    
    
	cout << val << " ";
}

class printVector2 {
    
    
public:
	void operator()(int val) {
    
    
		cout << val << " ";
	}
};

void test() {
    
    
	vector<int> v;
	for (int i = 0; i < 10; i++) {
    
    
		v.push_back(rand() % 100);
	}
	//普通函数直接用函数名
	cout << "普通函数:" << endl;
	for_each(v.begin(), v.end(), printVector1);
	cout << endl;
	//仿函数用函数对象
	cout << "仿函数:" << endl;
	for_each(v.begin(), v.end(), printVector2());
	cout << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.1.2 transform

在这里插入图片描述

#include<vector>
#include<algorithm>

void printVector(int val) {
    
    
	cout << val << " ";
}

class transRules {
    
    
public:
	int operator()(int val) {
    
    
		return ++val;
	}
};

void test() {
    
    
	vector<int> v1;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i);
	}
	for_each(v1.begin(), v1.end(), printVector);
	cout << endl;

	vector<int> v2;
	//目标容器 v2 必须提前设置大小
	v2.resize(v1.size());

	transform(v1.begin(),v1.end(),v2.begin(),transRules());

	for_each(v2.begin(), v2.end(), printVector);
	cout << endl;

}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.2 常用查找算法

在这里插入图片描述

5.2.1 find

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name,int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
	//自定义数据类型 重载 == 号便于查找
	bool operator==(const person &p) {
    
    
		if (this->m_name == p.m_name&&this->m_age == p.m_age) {
    
    
			return true;
		}
		else {
    
    
			return false;
		}
	}
};

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFGHIJK";
	for (int i = 0; i < 5; i++) {
    
    
		person p;
		p.m_name += nameSeed[i];
		//p.m_age = 25;
		p.m_age = 23 + rand() % 3;
		v.push_back(p);
	}

	person pFind("A",25);
	vector<person>::iterator pos = find(v.begin(), v.end(), pFind);
	if (pos == v.end()) {
    
    
		cout << "未找到一样的人" << endl;
	}
	else {
    
    
		cout << "找到一样的人" << endl;
	}
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.2.2 find_if

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
};

class Greater {
    
    
public:
	bool operator()(const person &p) {
    
    
		if (p.m_age > 25) {
    
    
			return true;
		}
		else {
    
    
			return false;
		}
	}
};

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFGHIJK";
	for (int i = 0; i < 5; i++) {
    
    
		person p;
		p.m_name += nameSeed[i];
		//p.m_age = 25;
		p.m_age = 23 + rand() % 4;
		v.push_back(p);
	}

	//自定义数据类型 用谓词进行操作
	vector<person>::iterator pos = find_if(v.begin(), v.end(), Greater());
	if (pos == v.end()) {
    
    
		cout << "未找到年龄大于25的人" << endl;
	}
	else {
    
    
		cout << "找到年龄大于25的人" << endl;
	}
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.2.3 adjacent_find

在这里插入图片描述

5.2.4 binary_search

在这里插入图片描述

  • 必须是有序排布的容器(递增或递减)

5.2.5 count

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
	//自定义数据类型 重载 == 进行操作
	bool operator==(const person &p) {
    
    
		if (this->m_age == p.m_age) {
    
    
			return true;
		}
		else {
    
    
			return false;
		}
	}
};

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
	for (int i = 0; i < 10; i++) {
    
    
		person p;
		p.m_name = nameSeed[i];
		p.m_age = rand() % 3 + 20;
		v.push_back(p);
	}
	person pCount("Z", 21);
	int num = count(v.begin(), v.end(), pCount);
	cout << "年龄相同的人数:" << num << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.2.6 count_find

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
};

class PCount {
    
    
public:
	bool operator()(const person &p) {
    
    
		return p.m_age == 20;
	}
};

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
	for (int i = 0; i < 10; i++) {
    
    
		person p;
		p.m_name = nameSeed[i];
		p.m_age = rand() % 3 + 20;
		v.push_back(p);
	}
	int num = count_if(v.begin(), v.end(), PCount());
	cout << "年龄相同的人数:" << num << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.3 常用排序算法

在这里插入图片描述

5.3.1 sort

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
};
//排序规则
class sortRules {
    
    
public:
	bool operator()(const person &p1, const person &p2) {
    
    
		return p1.m_age > p2.m_age;
	}
};
//打印函数
void printVector(const person &p) {
    
    
	cout << "姓名:" << p.m_name << " 年龄:" << p.m_age << endl;
}

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
	for (int i = 0; i < 10; i++) {
    
    
		person p;
		p.m_name = nameSeed[i];
		p.m_age = rand() % 10 + 20;
		v.push_back(p);
	}
	sort(v.begin(), v.end(), sortRules());
	for_each(v.begin(), v.end(), printVector);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.3.2 random_shuffle

在这里插入图片描述

//随机数种子
srand((unsigned)time(NULL));

5.3.3 merge

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
};
//排序规则
class sortRules {
    
    
public:
	bool operator()(const person &p1, const person &p2) {
    
    
		return p1.m_age > p2.m_age;
	}
};

void printVector(const person &p) {
    
    
	cout << "姓名:" << p.m_name << " 年龄:" << p.m_age << endl;
}

void test() {
    
    
	vector<person> v1;
	vector<person> v2;
	for (int i = 0; i < 10; i++) {
    
    
		person p1;
		p1.m_name = "A";
		p1.m_age = 20 + rand() % 10;
		v1.push_back(p1);
		
		person p2;
		p2.m_name = "B";
		p2.m_age = 20 + rand() % 10;
		v1.push_back(p2);
	}
	//两个合并的容器必须是有序的排列,同时递增或递减
	sort(v1.begin(), v1.end(), sortRules());
	sort(v2.begin(), v2.end(), sortRules());
	//需要给目标容器提取分配空间
	vector<person> vTarget;
	vTarget.resize(v1.size() + v2.size());
	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin(), sortRules());
	for_each(vTarget.begin(), vTarget.end(), printVector);
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.3.4 reverse

在这里插入图片描述

5.4 常用拷贝和替换算法

在这里插入图片描述

5.4.1 copy

在这里插入图片描述

5.4.2 replace

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
	bool operator==(const person &p) {
    
    
		return(this->m_name == p.m_name&&this->m_age == p.m_age);
	}
};

class printVector {
    
    
public:
	void operator()(const person &p) {
    
    
		cout << "姓名:" << p.m_name << " 年龄:" << p.m_age << endl;
	}
};

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
	for (int i = 0; i < 10; i++) {
    
    
		person p;
		p.m_name = nameSeed[0];
		p.m_age = rand() % 3 + 20;
		v.push_back(p);
	}
	cout << "替换前:" << endl;
	for_each(v.begin(), v.end(), printVector());

	person pOLD("A",22);
	person pNEW("a", 22000);
	replace(v.begin(), v.end(), pOLD, pNEW);
	cout << "替换后:" << endl;
	for_each(v.begin(), v.end(), printVector());
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.4.3 replace_if

在这里插入图片描述

#include<vector>
#include<algorithm>

class person {
    
    
public:
	string m_name;
	int m_age;
	person() {
    
    };
	person(string name, int age) {
    
    
		this->m_name = name;
		this->m_age = age;
	}
	//重载替换的 = 操作
	void operator=(string name) {
    
    
		this->m_name = name;
	}
};

class printVector {
    
    
public:
	void operator()(const person &p) {
    
    
		cout << "姓名:" << p.m_name << " 年龄:" << p.m_age << endl;
	}
};
//谓词,替换条件
class replaceRules {
    
    
public:
	bool operator()(const person&p) {
    
    
		return p.m_age > 30;
	}
};

void test() {
    
    
	vector<person> v;
	string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
	for (int i = 0; i < 10; i++) {
    
    
		person p;
		p.m_name = nameSeed[i];
		p.m_age = rand() % 10 + 25;
		v.push_back(p);
	}
	cout << "替换前:" << endl;
	for_each(v.begin(), v.end(), printVector());

	replace_if(v.begin(), v.end(), replaceRules(), "大龄青年");
	cout << "替换后:" << endl;
	for_each(v.begin(), v.end(), printVector());
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.4.4 swap

在这里插入图片描述

5.5 常用算术生成算法

在这里插入图片描述

5.5.1 accumulate

在这里插入图片描述

#include<numeric>
//第三个参数为 起始累加值
accumulate(v.begin(),v.end(),0);

5.5.2 fill

在这里插入图片描述

5.6 常用集合算法

在这里插入图片描述

5.6.1 set_intersection

在这里插入图片描述

#include<vector>
#include<algorithm>

void printVector(int val) {
    
    
	cout << val << " ";
}

void test() {
    
    
	//取交集的两个容器的元素必须是顺序排列的
	vector<int> v1;
	vector<int> v2;
	for (int i = 0; i < 10; i++) {
    
    
		v1.push_back(i);
		v2.push_back(i + 5);
	}

	vector<int> vTarget;
	//提前分配目标容器大小
	//目标容器的大小为 两个容器中较小的容器大小
	vTarget.resize(min(v1.size(), v2.size()));
	//返回的是一个迭代器
	vector<int>::iterator it_end = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
	cout << "交集为:" << endl;
	//遍历时使用it_end(系统返回的值) 不使用vTarget.end()
	for_each(vTarget.begin(), it_end, printVector);
	cout << endl;
}

int main() {
    
    
	srand((unsigned)time(NULL));
	test();
	return 0;
}

5.6.2 set_union

在这里插入图片描述

//目标容器大小
vTarget.resize(v1.size() + v2.size());

5.6.3 set_difference

在这里插入图片描述

  • 差集是所有元素除去交集部分后剩下的元素
  • v1与v2的差集 和 v2对与v1的差集 结果不同
//目标容器大小
vTarget.resize(max(v1.size(), v2.size()));

猜你喜欢

转载自blog.csdn.net/qq_52382976/article/details/121696986
今日推荐