C++提高编程

1、函数模板

#include<iostream>
using namespace std;

template<typename T>
void swapNum(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}

int main() {

	int a = 10;
	int b = 20;
	// 编译器自动猜测调用
	swapNum(a, b);
	cout << a << "  " << b << endl;

	float c = 1.1f;
	float d = 2.2f;
	// 告诉编译器类型调用
	swapNum<float>(c, d);
	cout << c << "  " << d << endl;

	return 0;
}

2、模板的注意事项

#include<iostream>
using namespace std;

// 模板必须要推导出一致的数据类型 推导出来的T的数据类型应该一致
// 模板必须要有数据类型

// 类模板 template<typename T> 函数模板
template<class T>
void swapVal(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}

template<typename T>
void func() {
	cout << "函数func的执行" << endl;
}

int main() {
	int a = 10;
	int b = 20;
	char c = 'c';
	// swapVal(a, c) ---->  报错 !!
	swapVal(a, b);
	cout << "a=" << a << "\tb=" << b << endl;

	// 必须确定T的类型才可以使用
	func<int>();

	return 0;
}

3、模板案例:数组排序

#include<iostream>
using namespace std;


template<typename T>
void swapVal(T& a, T& b) {
	T temp = a;
	a = b;
	b = temp;
}

// 排序算法
template<class T>
void mySort(T array[], int len) {
	for (int i = 0; i < len; i++)
	{
		int maxNum = i;
		for (int j = i + 1; j < len; j++)
		{
			if (array[maxNum] < array[j]) {
				maxNum = j;
			}
		}
		if (maxNum != i) {
			swapVal(array[maxNum], array[i]);
		}
	}
}

template<class T>
void printArray(T arr[], int len) {
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << "\n";
}

void test01() {
	// 测试char数组
	char charArr[] = "acbf";
	int len = sizeof(charArr) / sizeof(char);
	mySort(charArr, len);
	printArray(charArr, len);
}

void test02() {
	int arr[] = { 7, 5, 1, 9, 6, 4, 8 };
	int num = sizeof(arr) / sizeof(int);
	mySort(arr, num);
	printArray(arr, num);
}

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

4、普通函数与模板函数的区别

#include<iostream>
using namespace std;

// 普通函数调用时可以使用隐式类型转换
int myAdd(int a, int b) {
	return a + b;
}

// 模板函数自动确定参数时不能使用隐式类型转换
// 模板函数手动确定类型时可以使用隐式类型转换
template<class T>
int myAdd01(T a, T b) {
	return a + b;
}



void test01 () {
	int a = 10;
	int b = 1;
	cout << "a + b = " << myAdd(a, b) << endl;

	// 隐式类型转换为整形 ascii a = 97 ;
	char c = 'a';
	cout << "a + c = " << myAdd(a , c) << endl;

	// 无法推到出一致的数据类型 ---》 不会发生隐式类型转换,因为不知道应该转化为什么类型
	// cout << "a + c = " << myAdd01(a, c) << endl;

	// 手动传入模板数据类型 --》 显示指定数据类型, 最好调用时指定数据类型
	cout << "a + c = " << myAdd01<int>(a, c) << endl;
}

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

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

#include<iostream>
using namespace std;

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

// 如果都可以调用, 优先函数

// 可以通过空模板列表来调用,强制调用模板函数

// 如果模板函数可以产生更好的匹配,优先调用模板函数

void myPrint(int a, int b) {
	cout << "normal function" << endl;
}


template<class T>
void myPrint(T a, T b) {
	cout << "template function" << endl;
}

// 普通函数模板的重载
template<typename T>
void myPrint(T a, T b, T c) {
	cout << "best match template function" << endl;
}

void test01() {
	int a = 10;
	int b = 20;
	// call normal function even if only the func statement
	myPrint(a, b);
	// call template function 空模板的实现
	myPrint<>(a, b);
	// best match function
	int c = 10;
	my(a, b, c);
}

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

6、模板的局限性

#include<iostream>
using namespace std;

// 模板的局限性
// 具体的数据类型需要具体的实现

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

// 对比两个数据是否相等的函数
template<class T>
bool compare(T& a, T& b) {
	if (a == b)
	{
		return true;
	}
	else {
		return false;
	}
}

// 具体化Persson版本的实现, 具体化优先调用, 模板重载的使用, 注意,是具体化!!!
// 具体化模板需要加入参数 template<>
// 参入函数的参数种类必须相同:引用、指针、拷贝
template<> bool compare(Person& a, Person& b) {
	if (a.age == b.age && a.name == b.name)
	{
		return true;
	}
	else {
		return false;
	}
}

void test01() {
	// 普通类型对比
	int a = 10;
	int b = 20;
	bool ret = compare(a, b);
	cout << ret << endl;

	// 自定以类型对比
	Person p1("alex", 18);
	Person p2("alex", 18);
	// 此时编译器推不出什么类型, Person 与 Person 对比
	// 1、可以通过运算符重载
	// 2、单独指定具体化的Person数据类型
	// 这里用的是第二种
	bool retPerson = compare(p1, p2);
	cout << retPerson << endl;
}

int main() {
	test01();

	return 0;
}

7、类模板的基本语法

#include<iostream>
using namespace std;

template<class NameType, class AgeType>
struct Person {
	NameType name;
	AgeType age;
	Person(NameType name, AgeType age) {
		this->age = age;
		this->name = name;
	}
	void showPerson() {
		cout << "name = " << this->name << "\tage = " << this->age << endl;
	}
};



int main() {

	Person<string, int> p("alex", 18);
	p.showPerson();

	return 0;
}

8、类模板与函数模板的区别

#include<iostream>
using namespace std;

// 类模板与函数模板的区别
// 年龄默认是一个整型, 因此调用时可以不用传数据类型
// 只有类模板中才可以这样用
template<class NameType, class AgeType = int>
class Person {
public:
	NameType name;
	AgeType age;
	Person(NameType name, AgeType age) {
		this->name = name;
		this->age = age;
	}
	void showPerson() {
		cout << "name=" << this->name << "\tage=" << this->age << endl;
	}
};

// 类模板没有自动类型推导式
// 类模板参数列表中可以有默认参数
void test01() {
	// 错误的写法
	// Person p("alex", 18);
	// 无法用自动类型推到

	// 只能用显示指定类型
	Person<string, int> p("alex", 19);
	p.showPerson();
}

void test02() {
	Person<string> p_("tom", 10);
	p_.showPerson();
}



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

9、类模板中函数创建的时机

#include<iostream>
using namespace std;

// 普通类中函数开始就创建了

// 类模板中函数在调用时才开始创建

class Person1 {
public:
	void showPerson1() {
		cout << "normal 1 class" << endl;
	}
};

class Person2 {
public:
	void showPerson2() {
		cout << "normal 2 class" << endl;
	}
};

// 模板类
template<class T>
class TemplateClass {
public:
	T obj;
	
	// 在这里可以编译成功,因为成员函数只有在调用时才会创建
	void func1() {
		obj.showPerson1();
	}
	void fun2() {
		obj.showPerson2();
	}
};

void test() {
	TemplateClass<Person1> p;
	p.func1();

	// p.func2();
	// 调用失败,因为Person1里面没有成员函数
}

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

10、类模板对象做参数传参

#include<iostream>
using namespace std;

template<class T1, class T2>
class Person {
public:
	T1 name;
	T2 age;
	Person(T1 name, T2 age) {
		this->name = name;
		this->age = age;
	}
	void showPerson() {
		cout << "name=" << this->name << "\tage=" << this->age << endl;
	}
};

// 指定传入类型
void printPerson1(Person<string, int>& p) {
	p.showPerson();
}

void test01() {
	Person<string, int> p("alex", 18);
	printPerson1(p);
}

// 参数模板化
template<class T1, class T2>
void printPerson2(Person<T1, T2>& p) {
	p.showPerson();
	cout << "T1 的类型为:" << typeid(T1).name() << "\nT2的类型为:" << typeid(T2).name() << endl;
}

void test02() {
	Person<string, int> p1("tom", 19);
	printPerson2(p1);
}

// 整个类模板化
template<class T>
void printPerson3(T& p) {
	p.showPerson();
	cout << "T的类型为:" << typeid(p).name() << endl;
}

void test03() {
	Person<string, int> p2("jhon", 20);
	printPerson3(p2);
}


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

11、类模板与继承

#include<iostream>
using namespace std;


// 类模板继承
template<class T = int>
class Base {
public:
	
	T age;
};

// 必须要指定父类中T的数据类型
class Son : public Base<int> {
public:
	
};

// 如果想灵活指定属性, Son也应该是模板类
template<class T, class T1>
class SonTemplate : public Base<T> {
public:
	T1 name;
	SonTemplate(T age, T1 name) {
		this->age = age;
		this->name = name;
	}
	void showPerson() {
		cout << "name=" << this->name << "\tage=" << this->age << endl;
	}
};

void test01() {

	Son s1;

	int age = 18;
	string name = "alex";
	SonTemplate<int, string> sTmp(age, name);
	sTmp.showPerson();
}


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

12、类模板函数成员类外实现

#include<iostream>
using namespace std;

// 类模板成员函数类外实现
template<class T1, class T2>
class Person {
public:
	T1 name;
	T2 age;
	Person(T1 name, T2 age);
	void showPerson();
};

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

// 普通函数类外实现
template<class T1, class T2>
void Person<T1, T2>::showPerson() {
	cout << "name=" << this->name << "\tage=" << this->age << endl;
}


void test01() {
	Person<string, int> p("alex", 19);
	p.showPerson();
}


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

13、类模板的分文件编写

#include<iostream>
using namespace std;

// 类模板成员函数类外实现
template<class T1, class T2>
class Person {
public:
	T1 name;
	T2 age;
	Person(T1 name, T2 age);
	void showPerson();
};

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

// 普通函数类外实现
template<class T1, class T2>
void Person<T1, T2>::showPerson() {
	cout << "name=" << this->name << "\tage=" << this->age << endl;
}


void test01() {
	Person<string, int> p("alex", 19);
	p.showPerson();
}


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

14、类模板与友元

#include<iostream>
using namespace std;


// 通过全局函数来打印信息

// 声明 Person 类
template<class T1, class T2>
class Person;

// 先让编译器识别到类外模板全局函数,但是使用了Person, 因此需要先声明
template<class T1, class T2>
void printInfo2(Person<T1, T2>& p) {
	cout << "类外实现" << endl;
	cout << "name=" << p.name << "\tage=" << p.age << endl;
}

template<class T1, class T2>
class Person {
public:
	Person(T1 name, T2 age) {
		this->name = name;
		this->age = age;
	}
	// 在类的内部实现 全局函数
	friend void printInfo(Person<T1, T2>& p) {
		cout << "name=" << p.name << "\tage=" << p.age << endl;
	}
	// 全局函数在类外实现
	// 1、添加一个参数列表 <> , 需要让编译器提前知道这个函数的存在
	friend void printInfo2<>(Person<T1, T2>& p);
private:
	T1 name;
	T2 age;
};

void test01() {
	Person<string, int> p("alex", 20);

	printInfo(p);

	printInfo2(p);

}

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

15、类模板案例:数组封装

#include<iostream>
using namespace std;
#include"myArray19.hpp"

void test01() {

	MyArray<int> arr1(5);
	MyArray<int> arr2(arr1);
	MyArray<int> arr3(20);
	arr3 = arr1;
	for (int i = 0; i < 3; i++) {
		arr3.Push_Back(i + 1);
	}
	cout << arr3[1] << endl;
	arr3.Push_Back(40);
	cout << arr3[3] << endl;
	cout << "capacity:" << arr3.get_capacity() << endl;
	arr3.Pop_Back();
	cout << "size:" << arr3.get_size() << endl;arr3.Pop_Back();
	arr3.Pop_Back();
	cout << "size:" << arr3.get_size() << endl;
}


int main() {
	test01();
	return 0;
}
#pragma once
#include<iostream>
using namespace std;

template<class T>
class MyArray
{
public:
	MyArray(int capacity);
	~MyArray();

	MyArray(const MyArray& arr);
	MyArray& operator=(const MyArray& arr);
	
	void Push_Back(const T& val);
	void Pop_Back();
	T& operator[](int index);
	int get_capacity();
	int get_size();

private:
	T* address;
	int capacity;
	int size;
};

template<class T>
MyArray<T>::MyArray(int capacity)
{
	this->capacity = capacity;
	this->size = 0;
	this->address = new T[capacity];
}

template<class T>
MyArray<T>::~MyArray()
{
	if (this->address != NULL) {
		delete[] address;
		address = NULL;
	}
}

template<class T>
MyArray<T>::MyArray(const MyArray& arr) {
	this->capacity = arr.capacity;
	this->size = arr.size;
	this->address = new T[arr.capacity];
	for (int i = 0; i < this->size; i++) {
		this->address[i] = arr.address[i];
	}
}

template<class T>
MyArray<T>& MyArray<T>::operator=(const MyArray<T>& arr) {
	// 先判断原来堆区是否有数据
	if (this->address != NULL) {
		delete[] this->address;
		address = NULL;
		this->size = 0;
		this->capacity = 0;
	}
	this->capacity = arr.capacity;
	this->size = arr.size;
	this->address = new T[arr.capacity];
	for (int i = 0; i < this->size; i++) {
		this->address[i] = arr.address[i];
	}
	return *this;
}

template<class T>
void MyArray<T>::Push_Back(const T& val) {
	// 判断是否size 等于容量大小
	if (this->size == this->capacity)
	{
		return;
	}
	else {
		this->address[this->size] = val;
		this->size++;
	}
}

template<class T>
void MyArray<T>::Pop_Back() {
	if (this->size == 0) {
		return;
	}
	else {
		this->size--;
	}
}

template<class T>
T& MyArray<T>::operator[](int index) {
	return this->address[index];
}

template<class T>
int MyArray<T>::get_capacity() {
	return this->capacity;
}

template<class T>
int MyArray<T>::get_size() {
	return this->size;
}

16、vector容器

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>


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



void test01() {
	vector<int> v;

	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);

	// 指向第一个位置
	vector<int>::iterator iterBegin = v.begin();
	// 指向最后一个元素的下一个位置
	vector<int>::iterator iterEnd = v.end();

	// 第一种遍历方法
	/*
	while (iterBegin != iterEnd) {
		cout << *iterBegin << endl;
		iterBegin++;
	}
	*/
	// 第二种遍历方法
	/*
	for (vector<int>::iterator i = v.begin(); i != v.end(); i++) {
		cout << *i << endl;
	}
	*/
	// 第三种遍历算法
	for_each(v.begin(), v.end(), myPrint);

}


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

17、vector存放自定义数据

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


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

void test01() {
	vector<Person> person;
	Person p1("alex", 10);
	Person p2("tonm", 18);
	person.push_back(p1);
	person.push_back(p2);

	for (vector<Person>::iterator p = person.begin(); p != person.end(); p++) {
		cout << p->name << "\t" << (*p).age << endl;
	}
}

void test02() {
	vector<Person*> person;
	Person p1("alex", 10);
	Person p2("tonm", 18);
	person.push_back(&p1);
	person.push_back(&p2);

	for (vector<Person*>::iterator p = person.begin(); p != person.end(); p++) {
		cout << (*p)->name << "\t" << (**p).age << endl;
	}
}

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

18、容器嵌套容器

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



void test01() {

	vector<vector<int>> v;

	vector<int> v1;
	vector<int> v2;
	vector<int> v3;
	vector<int> v4;

	for (int i = 0; i < 4; i++) {
		v1.push_back(i);
		v2.push_back(i + 1);
		v3.push_back(i + 2);
		v4.push_back(i + 3);
	}

	v.push_back(v1);
	v.push_back(v2);
	v.push_back(v3);
	v.push_back(v4);

	for (vector<vector<int>>::iterator wrapper_iter = v.begin(); wrapper_iter != v.end(); wrapper_iter++) {
		for (vector<int>::iterator inner_iter = (*wrapper_iter).begin(); inner_iter != (*wrapper_iter).end(); inner_iter++) {
			cout << *inner_iter << " ";
		}
		cout << endl;
	}
}


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

19、string容器构造函数

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

// string 原始就是一个指针

void test01() {
	// 默认构造
	string s1;

	// 第一个
	const char* str = "hello world";
	string s2 = string(str);

	// 第二个
	string s3(s2);

	// 第三个 -> 十个 ‘a’的字符串
	string s4(10, 'a');
}

int main() {

	return 0;
}

20、string赋值操作

#include<iostream>
using namespace std;

// 赋值两种: asign, = 

void test01() {
	string s1;
	s1 = "Hello World";
	cout << "string1=" << s1 << endl;

	string s2;
	s2 = s1;
	cout << "string2=" << s2 << endl;

	string s3;
	s3 = 'a';
	cout << "string3=" << s3 << endl;

	string s4;
	s4.assign("hello C++");
	cout << "string4=" << s4 << endl;

	string s5;
	s5.assign("Hello C++", 5);
	cout << "string 5th = " << s5 << endl;

	string s6;
	s6.assign(s5);
	cout << "string6=" << s6 << endl;

	string s7;
	s7.assign(10, 'w');
	cout << "string7=" << s7 << endl;

}

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

21、string拼接

#include<iostream>
using namespace std;

void test01() {
	string str1 = "I";

	str1 += " like play games";

	cout << str1 << endl;

	str1 += ':';

	cout << str1 << endl;

	string str2 = "LoL DNF";

	str1 += str2;

	cout << str1 << endl;

}

void test02() {
	string s1 = "I";
	s1.append(" Love");
	cout << s1 << endl;
	s1.append(" game abcde", 5);
	cout << s1 << endl;
	string s2 = " LOL DNF";
	// 截取字符添加到原字符串的末尾
	// append(string, start, count);
	s1.append(s2, 0, 4);
	cout << s1 << endl;
}

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

22、字符串的查找和替换

#include<iostream>
using namespace std;

// 字符串的查找
void test01() {

	string s1 = "sasfsdafw";

	int position = s1.find('a');

	cout << "index=" << position << endl;
	cout << "找不到返回-1, 找到返回下标, 每次只会找到一个, 起始位置默认为0" << endl;
	
	int position_r = s1.rfind('a');
	cout << "position_r = " << position << endl;

}

// 字符串的替换
void test02() {

	string s1 = "abcdefg";

	// replace(start, count, target)
	// [start, count + start ) ---------> 再两端拼接
	s1.replace(1, 3, "11111");
	cout << s1 << endl;
}

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

23、string的比较操作

#include<iostream>
using namespace std;

void test01() {

	string s1 = "hello";
	string s2 = "hello";

	// 判断两个字符串是否相等, 按照ascii 逐个相互比较
	// == 对比的是两个字符串的首地址
	// ascii compare one by one
	if (s1.compare(s2) == 0) {
		cout << "s1 = s2" << endl;
	}
	else if (s1.compare(s2) > 0) {
		cout << "s1 > s2" << endl;
	}
	else {
		cout << "s1 < s2" << endl;
	}
}

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

24、字符串的存取

#include<iostream>
using namespace std;


void test01() {

	string str = "hello";

	cout << str << endl;

	// by []
	for (int i = 0; i < str.size(); i++) {
		cout << str[i] << " ";
	}
	cout << endl;

	// by at()
	for (int i = 0; i < str.size(); i++) {
		cout << str.at(i) << " ";
	}
	cout << endl;

	// modify cahr
	str[0] = 'x';
	cout << "modify: " << str << endl;

	str.at(1) = 'x';
	cout << "modify again: " << str << endl;

}

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

25、字符串的插入和删除

#include<iostream>
using namespace std;

void test01() {
	string str = "hello";

	// insert
	str.insert(1, "1111");
	// h1111llo
	cout << "insert in the second position:" << str << endl;

	// delete : erase
	// 从哪里开始删除, 删除几个
	str.erase(1, 4);
	cout << "erase: " << str << endl;
	
}

int main() {

	test01();

	return 0;
} 

26、字符串的获取

#include<iostream>
using namespace std;


void test() {

	string str = "abcdef";

	// 从 1 开始截取, 一共往后截取 3 个
	string subStr = str.substr(1, 3);

	cout << "subStr=" << subStr << endl;

}

void test01() {

	string email = "zhaomanXin@qq.com";

	int idx = email.find('@');

	cout << "index = " << idx << endl;

	string name = email.substr(0, idx);

	cout << "name = " << name << endl;
		
}




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

27、vector容器-构造函数

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


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

// vector 的 构造函数

void test01() {

	vector<int> v1;

	for (int i = 0; i < 5; i++) {
		v1.push_back(i);
	}
	showVector(v1);

	// 通过区间的方式进行构造 
	vector<int> v2(v1.begin(), v1.end());
	showVector(v2);

	// n个 element 方式构造
	vector<int> v3(10, 100);
	showVector(v3);

	// 拷贝构造
	vector<int> v4(v3);
	showVector(v4);

}


int main() {
	test01();

	return 0;
}

28、vector的赋值操作

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


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

void test01() {
	vector<int> v1;

	for (int i = 0; i < 5; i++) {
		v1.push_back(i);
	}

	showVector(v1);

	// 赋值操作
	vector<int> v2;
	v2 = v1;
	showVector(v2);


	// asign
	vector<int> v3;
	v3.assign(v1.begin(), v1.end());
	showVector(v3);

	// n 个 ele 的方式
	vector<int> v4;
	v4.assign(10, 100);
	showVector(v4);

}

int main() {

	test01();

	return 0;
}

29、vrector容器-容器大小

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


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





void test01() {

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

	cout << "判断是否为空:" << v1.empty() << endl;
	cout << "voctor的容量为: " << v1.capacity() << endl;
	cout << "容量永远大于大小" << endl;

	// 重新指定容量大小,  默认 为 0 来填充, resize(size, ele)
	v1.resize(15);
	printVector(v1);

	// 如果指定的比原来短, 默认会执行删除操作
	v1.resize(5);
	printVector(v1);

}


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

30、vector插入和删除

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

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


void test01() {

	vector<int> v1;
	// 尾插
	v1.push_back(10);
	v1.push_back(20);
	v1.push_back(30);
	v1.push_back(40);

	// 尾删
	v1.pop_back();
	printVector(v1);

	// 插入, 第一个迭代器
	v1.insert(v1.begin(), 100);
	printVector(v1);

	// 在开始的地方插入两个1000
	v1.insert(v1.begin(), 2, 1000);
	printVector(v1);
	

	// 删除
	v1.erase(v1.begin());
	printVector(v1);

	// 从头到尾全部清空
	// v1.rease(v1.begin(), v1.end());
	v1.clear();
	printVector(v1);
}


int main() {

	test01();
	return 0;
}

31、vector数据的存取

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

void test() {

	vector<int> v1;

	for (int i = 0; i < 5; i++) {
		v1.push_back(i);
	}

	// 遍历-----> 利用 [] 访问数组中的元素
	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;
}

32、vector互换容器

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


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

void test01() {
	// vector 容器互换
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	showVector(v1);

	vector<int> v2;
	for (int i = 10; i > 0; i--) {
		v2.push_back(i);
	}
	showVector(v2);

	cout << "容器的交换" << endl;
	v1.swap(v2);
	showVector(v1);
	showVector(v2);
	cout << "==========" << endl;

}

// 实际用途, 可以收缩大量的内存空间
void test02() {
	vector<int> v2;
	for (int i = 0; i < 1000; i++)
	{
		v2.push_back(i);
	}
	cout << "capacity: " << v2.capacity() << endl;
	cout << "size: " << v2.size() << endl;

	cout << "resize :" << endl;
	v2.resize(100); // 容量依然不改变
	 // 此时依然存在很大的空间
	cout << "capacity: " << v2.capacity() << endl;
	cout << "size: " << v2.size() << endl;

	// 巧用容器收缩
	// vector<int> (v) ----------> 调用拷贝构造函数
	// swap 相当于做了一个指针的交换
	// 匿名对象在改行执行完毕后会被回收
	vector<int>(v2).swap(v2);
	cout << "after swap myself: " << endl;
	cout << "capacity: " << v2.capacity() << endl;
	cout << "size: " << v2.size() << endl;
}

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

33、vector预留空间

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

void test01() {

	vector<int> v2;

	int num = 0;
	int* p = NULL;

	// 

	for (int i = 0; i < 1000; i++)
	{
		v2.push_back(i);
		if (p != &v2[0]) {
			p = &v2[0];
			num++;
		}
	}
	// 动态内存空间执行了 30 次
	cout << "num=" << num << endl;

}


void test02() {

	vector<int> v2;

	int num = 0;
	int* p = NULL;
	
	// 预留空间
	v2.reserve(1000);

	// 利用 reserve 来预留空间

	for (int i = 0; i < 1000; i++)
	{
		v2.push_back(i);
		if (p != &v2[0]) {
			p = &v2[0];
			num++;
		}
	}

	cout << "num=" << num << endl;

}

int main() {

	// test01();
	test02();

	return 0;
}

34、deque容器

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

/*
vector 头部插入 == 所有元素向后移动一位

deque 头部插入 == 在前面开辟一个新的地址, 不移动后面的元素

*/
void print(const deque<int>& d) {
	for (deque<int>::const_iterator deque_ = d.begin(); deque_ != d.end(); deque_++) {
		cout << *deque_ << " ";
	}
	cout << endl;
}

void test01() {

	deque<int> d1;
	for (int i= 0; i < 10; i++)
	{		
		d1.push_back(i);
	}
	print(d1);

	// 区间
	deque<int> d2(d1.begin(), d1.end());
	print(d2);

	deque<int> d3(10, 100);
	print(d3);

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


int main() {

	test01();
	return 0;
}

35、deque的赋值操作

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

void print(const deque<int>& d) {
	for (deque<int>::const_iterator d_ = d.begin(); d_ != d.end(); d_++) {
		cout << *d_ << " ";
	}
	cout << endl;
}

void test01() {
	
	deque<int> d1;

	for (int i = 0; i < 10; i++)
	{
		d1.push_back(i);
	}

	print(d1);

	// =======
	deque<int> d2;
	d2 = d1;
	print(d2);

	// ======
	deque<int> d3;
	d3.assign(d1.begin(), d1.end());
	print(d3);

	// ======
	deque<int> d4;
	d4.assign(10, 100);
	print(d4);
}

int main() {
	test01();

	return 0;
}

36、deque的大小操作

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


void print(const deque<int>& d_) {
	for (deque<int>::const_iterator d = d_.begin(); d < d_.end(); d++) {
		cout << *d << " ";
	}
	cout << endl;
}


void test01() {

	deque<int> d1;
	for (int i = 0; i < 10; i++) {
		d1.push_back(i);
	}

	if (d1.empty())
	{
		cout << "d1为空" << endl;
	}
	else {
		cout << "d1不为空" << endl;
		cout << "d1的大小为:" << d1.size() << endl;
		cout << "deque 没有容量的特点 capacity" << endl;
	}

	// ===========
	d1.resize(15, 1);
	print(d1);

	// ======
	d1.resize(5);
	print(d1);

}

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

37、deque的插入和删除

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


void print(const deque<int>& d_) {
	for (deque<int>::const_iterator d = d_.begin(); d < d_.end(); d++) {
		cout << *d << " ";
	}
	cout << endl;
}


void test01() {

	deque<int> d1;
	for (int i = 0; i < 10; i++) {
		d1.push_back(i);
	}

	if (d1.empty())
	{
		cout << "d1为空" << endl;
	}
	else {
		cout << "d1不为空" << endl;
		cout << "d1的大小为:" << d1.size() << endl;
		cout << "deque 没有容量的特点 capacity" << endl;
	}

	// ===========
	d1.resize(15, 1);
	print(d1);

	// ======
	d1.resize(5);
	print(d1);

}

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

38、deque数据存储

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

void test01() {

	deque<int> d1;

	d1.push_back(10);
	d1.push_back(100);
	d1.push_back(1000);
	d1.push_front(10);
	d1.push_front(100);
	d1.push_front(1000);
	
	// by []
	for (int i = 0; i < d1.size(); i++)
	{
		cout << d1[i] << " ";
	}
	cout << endl;

	// at()
	for (int i = 0; i < d1.size(); i++)
	{
		cout << d1.at(i) << " ";
	}
	cout << endl;

	cout << "第一个元素为: " << d1.front() << endl;
	cout << "最后一个元素为:" << d1.back() << endl;
}

int main() {

	test01();

	return 0;
}

39、deque排序操作

#include<iostream>
using namespace std;
#include<deque>
#include<algorithm>


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

void test01() {
	deque<int> d1;

	d1.push_back(10);
	d1.push_back(100);
	d1.push_back(1000);
	d1.push_front(1);
	d1.push_front(110);
	d1.push_front(1200);

	print(d1);

	// 排序操作, 包含标准算法
	// 支持访问迭代器的容器可以直接使用sort方法进行排序
	sort(d1.begin(), d1.end());
	cout << "排序后的deque:" << endl;

	print(d1);
}


int main() {

	test01();

	return 0;
}

40、vector&deque案例:评委打分

#include<iostream>
#include<vector>
#include<deque>
#include<algorithm>
#include<ctime>
using namespace std;

/*
有5名选手,ABCDE, 10个评委分别对每一个选手打分, 去掉最高分和最低分, 求平均分
*/
class Person {

public:
	string name;
	int score;

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


};

void createPerson(vector<Person>& person_vector) {
	string nameSeed = "ABCDE";
	for (int i = 0; i < 5; i++)
	{
		string name = "选手";
		name += nameSeed[i];
		int score = 0;
		Person p(name, score);
		person_vector.push_back(p);
	}
}

void setScore(vector<Person>& v) {
	for (vector<Person>::iterator v_ = v.begin(); v_ != v.end(); v_++) {
		// 将评委的分数放到deque容器中
		deque<int> d;
		for (int i = 0; i < 10; i++)
		{
			int score = rand() % 41 + 60; // 60 ~ 100
			d.push_back(score);
		}

		// 将容器进行排序
		sort(d.begin(), d.end());

		// 去除最高分和最低分
		d.pop_back();
		d.pop_front();

		// 取其平均分
		int sum = 0;
		for (int i = 0; i < d.size(); i++)
		{
			sum += d[i];
		}
		int avarge = sum / d.size();

		// 将平均分赋值给选手
		(*v_).score = avarge;
	}
}

void testPrint(vector<Person>& v) {
	for (int i = 0; i < v.size(); i++)
	{
		cout << "name=" << v[i].name << "\tscore=" << v[i].score << endl;
	}
	cout << endl;
}


int main() {
	// 加一个随机数种子 《time》
	srand((unsigned int)time(NULL));


	// 1 创建5名选手
	vector<Person> v;
	createPerson(v);

	// test
	testPrint(v);

	// 2 给五名选手打分
	setScore(v);

	// 3 求其平均分
	testPrint(v);

	

	return 0;
}

41、stack容器

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


// 先进后出


void test01() {
	stack<int> s;

	for (int i = 0; i < 5; i++)
	{
		s.push(i);
	}

	// 只要不为空, 那么就出 stack

	while (!s.empty()) {
		// 查看栈顶的元素
		cout << "栈顶的元素为:" << s.top() << endl;

		// 出栈
		s.pop();

	}

	cout << "栈的大小为:" << s.size() << endl;
	

}

int main() {
	
	system("color e");

	test01();

	return 0;
}

42、deque的常用接口

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

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

// 队列

void test01() {
	queue<Person> q;

	Person p0("alex", 19);
	Person p1("tom", 20);
	Person p2("bob", 21);

	q.push(p0);
	q.push(p1);
	q.push(p2);

	cout << "队列的大小为:" << q.size() << endl;

	// 只要队列不为空, 那么就查看 队尾, 队 头
	while (!q.empty()) {
		cout << "队列头部的元素\t" << "name=" << q.front().name << "\tage=" << q.front().age << endl;
		cout << "队列尾部的元素\t" << "name=" << q.back().name << "\tage=" << q.back().age << endl;
		// 移除队列中的元素
		q.pop();
		cout << endl;
	}

	cout << "队列的大小为:" << q.size() << endl;
}

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

43、list容器

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

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


void test01() {
	list<int> l;

	// 添加数据
	for (int i = 0; i < 8; i++) {
		l.push_back(i);
	}

	// 遍历数据
	print(l);

	list<int> l2(l.begin(), l.end());
	print(l2);

	list<int> l3(l2);
	print(l3);

	list<int> l4(10, 1000);
	print(l4);
}


int main() {

	test01();
	return 0;
}

44、list容器的赋值与操作

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


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

void test() {
	list<int> l1;
	for (int i = 0; i < 10; i++)
	{
		l1.push_back(i);
	}
	print(l1);


	list<int> l2;
	l2 = l1;
	print(l2);

	list<int> l3;
	l3.assign(l1.begin(), l1.end());
	print(l3);

	list<int> l4;
	l4.assign(10, 100);
	print(l4);
}

void test02() {

	list<int> l1;
	l1.push_back(10);
	l1.push_back(20);
	l1.push_back(30);
	l1.push_back(40);

	list<int> l2;
	l2.assign(10, 100);

	cout << "交换之前:" << endl;
	print(l1);
	print(l2);

	cout << "交换之后:" << endl;
	l1.swap(l2);

	print(l1);
	print(l2);

}

int main() {

	//test();
	test02();
	return 0;
}

45、list容器的大小与操作

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



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


void test01() {

	list<int> l1;
	l1.push_back(10);
	l1.push_back(20);
	l1.push_back(30);
	l1.push_back(40);

	// 判断容器是否为空
	if (l1.empty())
	{
		cout << "list容器为空" << endl;
	}
	else {
		cout << "list不为空" << endl;
		cout << "list的size为:" << l1.size() << endl;

	}

	// 重新指定大小
	l1.resize(10, 1000);
	print(l1);


	l1.resize(3);
	print(l1);
}


int main() {
	test01();

	return 0;
}

46、list容器的插入和删除

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



void print(list<int>& lst) {
	for (list<int>::iterator ls = lst.begin(); ls != lst.end(); ls++) {
		cout << *ls << " ";
	}
	cout << endl;
}


// list 的插入和删除

void test01() {
	list<int> lst;

	// 尾部插入
	lst.push_back(10);
	lst.push_back(20);
	lst.push_back(30);

	// 头部插入
	lst.push_front(100);
	lst.push_front(200);
	lst.push_front(300);

	print(lst);

	// 尾部删除
	lst.pop_back();

	// 头部删除
	lst.pop_front();

	print(lst);

	// insert() 插入
	list<int>::iterator begin = lst.begin();
	begin++;
	
	lst.insert(begin, 1000);
	
	// cout << begin << endl;
	// 删除, 插入成功后,迭代器指向的地址将向后移动一位
	lst.erase(begin);
	print(lst);

	// 移除
	// 移除容器中所有与之匹配的元素
	lst.push_back(10000);
	lst.push_back(10000);
	print(lst);
	cout << "remove" << endl;
	lst.remove(10000);
	print(lst);

	// 清空
	cout << "begin clear" << endl;
	lst.clear();
	print(lst);
	cout << "end clear" << endl;
}


int main() {

	test01();
	return 0;
}

47、list容器数据的存取

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


// lst 数据存取

void test01() {
	list<int> l1;

	l1.push_back(10);
	l1.push_back(20);
	l1.push_back(30);
	l1.push_back(40);

	// 不能通过 [] 的方式访问list 容器
	// 也不能通过 at() 访问 list 中的数据
	// 原因, list 的本质就是一个链表, 本身的数据就是一个不是连续的

	cout << "第一个元素:" << l1.front() << endl;
	cout << "最后一个元素:" << l1.back() << endl;

	// 迭代器是不支持随机访问的: 因为 it = it+ 1: 不能跳跃式的访问
	list<int>::iterator it = l1.begin();

	// it = it + 1 : 不允许这样的操作, 
	it++;
	// it-- : 只支持双向递增 或者 递减

}


int main() {
	test01();

	return 0;
}

48、list容器的反转和排序

#include<iostream>
#include<list>
#include<algorithm>
using namespace std;


void print(list<int>& lst) {

	for (list<int>::iterator ls = lst.begin(); ls != lst.end(); ls++) {
		cout << *ls << " ";
	}
	cout << endl;

}

void test01() {
	// 反转
	list<int> lst;

	lst.push_back(10);
	lst.push_back(20);
	lst.push_back(30);
	lst.push_back(40);

	cout << "反转前的打印" << endl;
	print(lst);
	cout << "反转后的打印" << endl;
	lst.reverse();
	print(lst);

}

bool myCompare(int v1, int v2) {
	return v1 > v2;
}

// 排序
void test02() {
	list<int> lst;

	lst.push_back(10);
	lst.push_back(20);
	lst.push_back(9);
	lst.push_back(11);

	cout << "排序之前" << endl;

	// 随机访问迭代器的容器不可以使用标准算法
	// 内部自动提供
	// sort(lst.begin(), lst.end());
	// 默认的排序规则
	lst.sort();
	// lst.reverse();
	print(lst);
	cout << "排序之后" << endl;

	// 降序
	lst.sort(myCompare);
	print(lst);
	cout << "降序之后" << endl;
}


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

49、list容器排序

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

// 按照年龄进行升序, 年龄相同降序

struct Person {
	int age;
	int height;
	string name;

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


bool myCompare(Person p1, Person p2) {
	if (p1.age == p2.age) {
		return p1.height > p2.height;
	}
	else {
		return p1.age < p2.age;
	}
}


void test() {

	list<Person> lst;
	Person p1("刘备", 35, 175);
	Person p2("赵云", 45, 180);
	Person p3("曹操", 40, 170);
	Person p4("赵云", 25, 190);
	Person p5("张飞", 35, 160);
	Person p6("关羽", 35, 200);

	lst.push_back(p1);
	lst.push_back(p2);
	lst.push_back(p3);
	lst.push_back(p4);
	lst.push_back(p5);
	lst.push_back(p6);

	cout << "排序之前" << endl;
	for (list<Person>::iterator ls = lst.begin(); ls != lst.end(); ls++) {
		cout << "name=" << ls->name << "\tage=" << ls->age << "\theight" << ls->height << endl;
	}
	cout << "排序之后" << endl;
	lst.sort(myCompare);
	for (list<Person>::iterator ls = lst.begin(); ls != lst.end(); ls++) {
		cout << "name=" << ls->name << "\tage=" << ls->age << "\theight" << ls->height << endl;
	}
}

int main() {

	test();
	return 0;
}

50、set容器构造和赋值

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

// set ----> 不能有相同的元素
// multiset --》 二叉树:允许有重复的元素

void printSet(set<int> s) {
	for (set<int>::iterator it = s.begin(); it != s.end(); it++) {

		cout << *it << " ";

	}
	cout << endl;
}

void test01() {

	set<int> s1;

	// set 容器中的数据不会重复
	// 插入数据只有 insert 这一种方式
	s1.insert(10);
	s1.insert(20);
	s1.insert(40);
	s1.insert(30);
	
	// set 容器的特点:所有被插入的元素都会自动排序
	// set 容器不允许重复值
	printSet(s1);

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

	// 等号赋值, 指针构造
	set<int> s3(s1.begin(), s1.end());
	printSet(s3);

}


int main() {

	test01();

	return 0;
}

51、set容器set大小与交换

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


// 不支持 resize();


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


void test01() {

	set<int> s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);

	// 判断是否为空
	if (s1.empty()) {
		cout << "为空" << endl;
	}
	else {
		cout << "s1不为空" <<  endl;
	}

	set<int> s2;
	s2.swap(s1);
	printSet(s1);
	printSet(s2);

}

int main() {

	test01();
	return 0;
}

52、set容器的插入和删除

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

/*

insert(num)

clear()

erase(pos)

erase(beg, end)

erase(ele)


*/

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


void test01() {
	set<int> s1;

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

	// 遍历
	printSet(s1);
	// 删除
	s1.erase(s1.begin());
	// 删除的是第一个元素, 容器中的第一个数据为排序后的数据
	// 和插入数据没有关系
	printSet(s1);

	// ele 删除
	s1.erase(30);
	printSet(s1);

	// 清空
	s1.clear();
	printSet(s1);
}

int main() {
	system("color e");
	test01();

	return 0;
}

53、set的查找和统计

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


void test01() {
	// find() , count();  ---> 指针(迭代器指向元素的位置)
	set<int> s1;

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

	set<int>::iterator it = s1.find(20);
	if (it != s1.end())
	{
		cout << " 找到元素 :" << *it << endl;
	}
	else {
		cout << "没有找到元素" << endl;
	}


}

void test02() {
	set<int> s1;

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

	// 统计30的个数
	int num = s1.count(30);
	// 对于set来说, 统计的元素要么是 0 要么是 1
	cout << "三十的个数为:" << num << endl;
}



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

54、set和multiset的区别

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


void test01() {
	set<int> s1;

	s1.insert(10);
	// s1.insert(10);
	// 里面只会存在一个元素

	// 但是 -》 队组 pair, 可以查看是否插入成功
	pair<set<int>::iterator, bool> ret = s1.insert(20);

	// 拿到第二个数据  second -> bool
	if (ret.second) {
		cout << "第一次插入成功了 !" << endl;
	}
	else {
		cout << "插入失败了" << endl;
	}

	// 但是 -》 队组 pair, 可以查看是否插入成功
	pair<set<int>::iterator, bool> ret1 = s1.insert(20);

	// 拿到第二个数据  second -> bool
	if (ret1.second) {
		cout << "第一次插入成功了 !" << endl;
	}
	else {
		cout << "插入失败了" << endl;
	}

}


void test02() {
	multiset<int> s1;

	s1.insert(10);
	// s1.insert(10);
	// 里面只会存在一个元素

	// 但是 -》 队组 pair, 可以查看是否插入成功
	multiset<int>::iterator ret = s1.insert(20);

	// 返回的是插入元素的指针
	cout << "被插入的元素返回的指针的对应指向的值为:" << *ret << endl;
	
}



int main() {

	test01();
	cout << "==============" << endl;
	test02();
	return 0;
}

55、pair队组的创建

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


void test() {
	// 第一种创建方式
	pair<string, int> p("tom", 18);

	cout << "name=" << p.first << "\tage=" << p.second << endl;

	// 第二种方式创建队组
	pair<string, int> p2 = make_pair("alex", 19);
	cout << "name=" << p2.first << "\tage=" << p2.second << endl;


}

int main() {
	test();

	return 0;
}

56、set容器内置指定排序规则

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

// 仿函数
class MyComaper {
public:
	// 第一个()是用来重载的, 第二个()是用来当作参数列表的
	bool operator()(int v1, int v2) const {
		return v1 > v2;
	}
};

void test() {

	set<int> s1;

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

	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;

	// 指定排序规则, 仿函数 MyCompare
	set<int,  MyComaper> s2;

	s2.insert(10);
	s2.insert(20);
	s2.insert(40);
	s2.insert(30);

	for (set<int, MyComaper>::iterator it = s2.begin(); it != s2.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

int main() {
	test();

	return 0;
}

57、set容器自定义指定类型排序

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


class Person {

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

};

class MyCompaer {
public:
	bool operator()(Person p1, Person p2) const {
		return p1.age < p2.age;
	}
};


void test() {
	Person p1("aLEX", 18);
	Person p2("tom", 19);
	Person p3("john", 20);

	set<Person, MyCompaer> s;
	s.insert(p1);
	s.insert(p2);
	s.insert(p3);

	for (set<Person, MyCompaer>::iterator it = s.begin(); it != s.end(); it++) {
		cout << "name=" << it->name << "\tage=" << it->age << endl;
	}


}

int main() {
	test();

	return 0;
}

58、map容器构造与赋值

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

/*
map key 不允许重复

multimap  key 允许重复-
*/
void printMap(map<int, int>& m) {
	for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
		cout << "key: " << it->first << "\tvalue: " << it->second << endl;
	}
}

void test() {
	map<int, int> m;

	// 匿名的队组, m中第一个
	m.insert(pair<int, int>(1, 10));
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(3, 30));

	printMap(m);

	// 拷贝构造
	cout << "拷贝构造" << endl;
	map<int, int> m1(m);
	printMap(m1);

	// 赋值
	cout << "赋值构造" << endl;
	map<int, int> m2;
	m2 = m1;
	printMap(m2);
}

int main() {
	test();

	return 0;
}

59、map容器的大小和互换

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

void test() {
	// size empty swap
	// map 容器的大小 以及 交换案例
	map<int, int> m;
	m.insert(pair<int, int>(1, 10));
	m.insert(pair<int, int>(2, 20));
	m.insert(pair<int, int>(3, 30));

	if (m.empty()) {
		cout << "empty !" << endl;
	}
	else {
		cout << "not empty !" << endl;

	}
}

int main() {
	test();

	return 0;
}

60、map的插入和删除

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

void print(map<int, int> m) {
	for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
		cout << it->first << " " << it->second << endl;
	}

}

void test() {

	map<int, int> m;

	m.insert(pair<int, int>(1, 10));

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

	// 第三种, 不会怎么用
	m.insert(map<int, int>::value_type(30, 30));

	// 第四种, 不建议
	m[4] = 40;
	// 不建议用于插入, 但是可以通过key-val的方式来访问 【】 值
	// 写一个key不存在的数会导致插入错误
	cout << m[5] << " " << endl;

	print(m);

	//删除
	m.erase(m.begin());
	cout << "删除了第一个元素" << endl;
	print(m);
	
	// erase 只会根据key的索引值来删除元素
	cout << "删除了一个索引值为10的值" << endl;
	m.erase(10);
	print(m);

	// 根据区间来删除, 或者直接 clear
	cout << "清空了!" << endl;
	m.clear();
	print(m);
}


int main() {
	test();

	return 0;
}

61、map容器的查找和统计

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


void test() {
	map<int, int> m;

	m.insert(pair<int, int>(10, 10));
	m.insert(pair<int, int>(20, 20));
	m.insert(pair<int, int>(30, 30));

	map<int, int>::iterator pos = m.find(3);
	cout << "查找key=3的元素" << endl;
	if (pos != m.end())
	{
		cout << "find: " << "key=" << pos->first << "\tval=" << pos->second << endl;
	}
	else {
		cout << "not find !" << endl;
	}

	// 统计个数为三的元素
	cout << "m中3的元素的个数为:" << endl;
	int num = m.count(3);
	cout << "key=3\tcount=" << num << endl;
	cout << "cout  结果要么是0, 要么是1, 因为map容器元素不能重复" << endl;
	// map中的key值不能相同, 不能重复插入
}


int main() {
	test();

	return 0;
}

62、map容器的排序

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


// 仿函数, 改变排序方式
class MyCompaer {
public:
	bool operator()(int v1, int v2) const {
		return v1 > v2;
	}

};


void print(map<int, int, MyCompaer> m) {
	for (map<int, int, MyCompaer>::iterator it = m.begin(); it != m.end(); it++) {
		cout << it->first << " " << it->second << endl;
	}

}

void test() {
	map<int, int, MyCompaer> m;

	m.insert(make_pair(10, 10));
	m.insert(make_pair(20, 20));
	m.insert(make_pair(30, 30));

	print(m);

}

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

63、案例:员工分组

#include<iostream>
using namespace std;
#include<vector>
#include<ctime>
#include<map>

constexpr int CEHUA = 0;
constexpr int MEISHU = 1;
constexpr int YANFA = 2;

struct Worker {
	string name;
	int salary;
};

void createWorker(vector<Worker>& worker) {
	srand((unsigned int)time(NULL));
	string nameSeed = "ABCSDEFGHIJ";
	for (int i = 0; i < 10; i++)
	{
		Worker w;
		w.name = "员工";
		w.name += nameSeed.at(i);
		w.salary = rand() % 101 + 100;
		worker.push_back(w);
	}
}

void print(const vector<Worker> worker) {
	for (vector<Worker>::const_iterator it = worker.begin(); it != worker.end(); it++) {
		cout << "name = " << it->name << "\tsalary = " << it->salary << endl;
	}
}


void groupWorker(vector<Worker>& worker ,multimap<int, Worker>& worker_group) {
	for (vector<Worker>::iterator it = worker.begin(); it != worker.end(); it++) {
		// 创建部门编号 0, 1, 2
		int depId = rand() % 3;

		cout << "depId=" << depId << "\t\tname = " << it->name << "\tsalary = " << it->salary << endl;

		// 将员工插入分组中
		worker_group.insert(pair<int, Worker>(depId, *it));
	}
}

void showWorkerByGroup(multimap<int, Worker>& worker_group, int typeName) {
	multimap<int, Worker>::iterator begin = worker_group.find(typeName);
	int count = worker_group.count(typeName);
	int counter = 0;
	switch (typeName)
	{
		case MEISHU : {
			cout << "美术部门员工:" << endl;
			break;
		}
		case CEHUA: {
			cout << "策划部门员工:" << endl;
			break;
		}
		case YANFA: {
			cout << "研发部门员工:" << endl;
			break;
		}
	default:
		cout << "没有找到该部门!" << endl;
		return;
	}
	for (; begin != worker_group.end() && counter < count; counter++, begin++) {
		cout << "\tname=" << begin->second.name << "\tsalary:" << begin->second.salary << endl;
	}
}

int main() {

	system("color e");

	// 创建员工
	vector<Worker> worker;
	createWorker(worker);
	cout << "创建员工:" << endl;
	print(worker);

	//给员工分组
	multimap<int, Worker> worker_group;
	cout << "\n员工分组:" << endl;
	groupWorker(worker, worker_group);


	// 显示分组后的员工
	cout << "\n显示员工:" << endl;
	showWorkerByGroup(worker_group, MEISHU);
	showWorkerByGroup(worker_group, CEHUA);
	showWorkerByGroup(worker_group, YANFA);

	return 0;
}

64、函数对象的基本使用

#include<iostream>
using namespace std;

// 函数对象: 本质上是一个类

class MyAdd {
public:
	int operator()(int v1, int v2) {
		return v1 + v2;
	}

};

class MyPrint {
public:
	int count;
	MyPrint(int count = 0) {
		this->count = count;
	}
	void operator()(string str) {
		cout << str << endl;
		//记录一共调用了多少次
		this->count++;
	}
};


void test01() {

	int a = 10;
	int b = 20;

	MyAdd myadd;
	int c = myadd(a, b);
	cout << "实例化对象函数调用 c=" << c << endl;

}

void doPrint(MyPrint& print, string str) {
	print(str);
}

void test02() {

	MyPrint print;
	print("hello world");
	print("hello world");
	print("hello world");
	print("hello world");
	cout << "print的调用次数为:" << print.count << endl;
	
	doPrint(print, "call by do print");
}

int main() {

	// test01();
	test02();

	return 0;
}

65、谓词-一元谓词

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

// 谓词:返回布尔类型的仿函数
// 形参中几个参数就是几元谓词

struct MyCompaer {
	bool operator()(int val) {
		return val > 5;
	}
};


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

	// 查找容器中有没有大于 5 的数字
	//MyCompaer() 匿名函数对象 -》 执行了实例化, 但是对象是匿名
	vector<int>::iterator it =  find_if(v.begin(), v.end(), MyCompaer());
	if (it == v.end())
	{
		cout << "没有找到" << endl;
	}
	else {
		cout << "找到了" << endl;
		cout << *it << endl;
	}
}


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

66、二元谓词

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include"common.h"

struct MyCompare{

	bool operator()(int v1, int v2) const {
		return v1 > v2;
	}

};

void test01() {
	vector<int> v;
	v.push_back(1);
	v.push_back(4);
	v.push_back(2);
	v.push_back(3);
	v.push_back(5);

	sort(v.begin(), v.end());

	printVectorInt(v);

	// 定义函数, 排序规则从大到小
	sort(v.begin(), v.end(), MyCompare());

	printVectorInt(v);
}

int main() {

	test01();
	return 0;
}

67、内建函数对象

#include<iostream>
using namespace std;
#include<algorithm>
#include<functional>


// negate 取反
void test01() {

	negate<int> func;

	cout << func(50) << endl;


}





// plus 

void test02() {

	plus<int> func;

	minus<int> func1;
	modulus<int> func2;

	cout << func(10, 20) << endl;

}

int main() {

	test01();
	test02();
	return 0;
}

68、内建函数对象-关系仿函数

#include<iostream>
using namespace std;
#include<vector>
#include"common.h"
#include<algorithm>


struct MyCompare {

	bool operator()(int v1, int v2) const {
		return v1 > v2;
	}

};


void test() {

	vector<int> v;
	v.push_back(1);
	v.push_back(3);
	v.push_back(5);
	v.push_back(4);

	printVectorInt(v);

	// 排序
	sort(v.begin(), v.end(), MyCompare());
	printVectorInt(v);

	// 内建函数对象
	sort(v.begin(), v.end(), greater<int>());
	//sort(v.begin(), v.end(), less<int>());
	printVectorInt(v);
}

int main() {

	test();

	return 0;
}

69、逻辑仿函数

#include<iostream>
using namespace std;
#include<vector>
#include"common.h"
#include<algorithm>
#include<functional>

// 逻辑非 logical-not ---> 仿函数

void test() {

	vector<bool> v;

	v.push_back(true);
	v.push_back(false);
	v.push_back(true);
	v.push_back(true);

	printVectorBool(v);

	// 利用逻辑非
	vector<bool> v2;

	// 目标容器必须先开辟一个空间
	v2.resize(v.size());
	
	transform(v.begin(), v.end(), v2.begin(), logical_not<bool>());
	printVectorBool(v2);

}


int main() {

	test();

	return 0;
}

70、遍历算法for_each

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>


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

struct Print {
	void operator()(int val) {
		cout << val << " ";
	}
};

// 遍历 for each
// 遍历搬运 tramsform
void test01() {

	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	// 回调函数
	for_each(v.begin(), v.end(), print);
	cout << endl;

	for_each(v.begin(), v.end(), Print());
	cout << endl;
}

int main() {

	test01();

	return 0;
}

71、遍历算法transform

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>


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

struct Print {
	void operator()(int val) {
		cout << val << " ";
	}
};

// 遍历 for each
// 遍历搬运 tramsform
void test01() {

	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	// 回调函数
	for_each(v.begin(), v.end(), print);
	cout << endl;

	for_each(v.begin(), v.end(), Print());
	cout << endl;
}

int main() {

	test01();

	return 0;
}

72、查找算法find

#include<iostream>
using namespace std;
#include<vector>
#include"common.h"

// 查找内置
void test() {
	vector<int> v;
	for (int i = 0; i < 5; i++)
	{
		v.push_back(i);
	}

	vector<int>::iterator it = find(v.begin(), v.end(), 4);
	cout << *it << endl;

}

struct Person {
	string name;
	int age;
	Person(string name, int age) {
		this->name = name;
		this->age = age;
	}
	bool operator==(const Person p2) {
		if (this->name == p2.name && this->age == p2.age) {
			return true;
		}
		else {
			return false;
		}
	}
};


// 查找自定义数据类型
void test01() {
	Person p1("alex", 18);
	Person p2("tom", 18);
	Person p3("jhon", 19);

	vector<Person> v;
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);

	vector<Person>::iterator it = find(v.begin(), v.end(), p2);
	cout << it->name << " " << it->age << endl;
}

int main() {

	// test();
	test01();
	return 0;
}

73、查找算法find_if

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

struct Compare {
	bool operator()(int v1) {
		return v1 > 5;
	}
};

void test01() {

	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);

	}

	vector<int>::iterator it = find_if(v.begin(), v.end(), Compare());
	cout << *it << endl;
}

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

class PersonCompaer {
public:
	bool operator() (Person p1) {
		return p1.age > 18;
	}
};

void test02() {
	Person p1("alex", 18);
	Person p2("tom", 18);
	Person p3("jhon", 19);

	vector<Person> v;
	v.push_back(p1);
	v.push_back(p2);
	v.push_back(p3);

	vector<Person>::iterator it = find_if(v.begin(), v.end(), PersonCompaer());
	cout << it->name << " " << it->age << endl;
}

int main() {

	test01();
	test02();
	return 0;
}

74、查早算法adjacent_find

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>

// 查找重负的, 相邻的元素

void test01() {
	vector<int> v;
	v.push_back(1);
	v.push_back(0);
	v.push_back(0);
	v.push_back(0);

	vector<int>::iterator it = adjacent_find(v.begin(), v.end());

	cout << *it << endl;

}


int main() {

	test01();

	return 0;
}

75、查找算法binary_search

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>;

// 返回的是一个布尔值

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);

	}

	bool isExist = binary_search(v.begin(), v.end(), 9);

	cout << isExist << endl;


}

int main() {

	test01();

	return 0;
}

76、查找算法count

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

void test01() {

	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	int num = count(v.begin(), v.end(), 5);

	cout << num << endl;

}



int main() {


	return 0;
}

77、查找算法count_if

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

bool compare(int v1) {
	return v1 == 1;
}


void test01() {

	vector<int> v1;

	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);
	v1.push_back(1);

	int num = count_if(v1.begin(), v1.end(), compare);
	cout << num << endl;
}


int main() {
	test01();

	return 0;
}

78、排序算法sort

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include"common.h"
#include<functional>


void print(int num) {
	cout << num << " ";
}

void test01() {
	vector<int> v;

	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), print);
	cout << endl;

	random_shuffle(v.begin(), v.end());

	printVectorInt(v);

	sort(v.begin(), v.end(), greater<int>());

	printVectorInt(v);

}


int main() {

	test01();

	return 0;
}

79、排序算法random_shulff

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include"common.h"
#include<functional>


void print(int num) {
	cout << num << " ";
}

void test01() {
	vector<int> v;

	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	for_each(v.begin(), v.end(), print);
	cout << endl;

	// ===========================
	random_shuffle(v.begin(), v.end());

	printVectorInt(v);

	sort(v.begin(), v.end(), greater<int>());

	printVectorInt(v);

}


int main() {

	test01();

	return 0;
}

80、排序算法merge

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>

void print(int v) {

	cout << v << " ";
}



void test01() {
	vector<int> v1;
	vector<int> v2;

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}
	for (int i = 11; i < 20; i++)
	{
		v2.push_back(i);
	}

	vector<int> target;
	target.resize(v1.size() + v2.size());

	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin());

	for_each(target.begin(), target.end(), print);
	cout << endl;
}


int main() {

	test01();
	return 0;
}

81、排序算法reverse

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include"common.h"

void test01() {
	vector<int> v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}
	printVectorInt(v);

	reverse(v.begin(), v.end());

	printVectorInt(v);
}

int main() {

	test01();
	return 0;
}

82、常用拷贝与替换算法

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
#include"common.h"

void test01() {
	vector<int> v1;
	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	vector<int> v2;
	v2.resize(v1.size());

	copy(v1.begin(), v1.end(), v2.begin());

	printVectorInt(v2);
}


int main() {

	test01();
	return 0;
}

83、替换算法replace

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include"common.h"

struct Print
{
	void operator()(int s) {
		cout << s << " ";
	}
};

void test() {

	vector<int> v;

	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	printVectorInt(v);

	// 替换所有的元素
	replace(v.begin(), v.end(), 3, 1000);

	for_each(v.begin(), v.end(), Print());
	cout << endl;

}


int main() {

	test();

	return 0;
}

84、拷贝替换算法swap

#include<iostream>
using namespace std;

// v.swap(v2)
// v 的值和 v2 的值相互交换


int main() {


	return 0;
}

85、拷贝与替换算法replace_if

#include<iostream>
using namespace std;
#include<vector>
#include"common.h"
#include<algorithm>

struct Compare {
	bool operator() (int a){
		return a > 5;
	}
};

void test() {

	vector<int> v;

	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	printVectorInt(v);

	// 替换所有的元素
	replace_if(v.begin(), v.end(), Compare(), 100);

	printVectorInt(v);



}

int main() {

	test();

	return 0;
}

86、算数生成算法accumulate

#include<iostream>
using namespace std;
#include<vector>
#include<numeric>

void test01() {
	vector<int> v;

	for (int i = 0; i <= 100; i++)
	{
		v.push_back(i);
	}
	
	// 第三个参数起始位置的累加值, 不需要的话就写0
	int total = accumulate(v.begin(), v.end(), 0);

	cout << total << endl;
}

int main() {

	test01();
	return 0;
}

87、算数生成算法fill

#include<iostream>
using namespace std;
#include<vector>
#include<numeric>
#include"common.h"

void test01() {
	vector<int> v;
	v.resize(10);

	fill(v.begin(), v.end(), 100);
	printVectorInt(v);
}


int main() {

	test01();
	return 0;
}

88、集合算法setintersection

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include"common.h"
// 集合的交集

void print(int v) {
	cout << v << " ";
}

void test01() {
	vector<int> v1;
	vector<int> v2;

	vector<int> v3;

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	for (int i = 2; i < 15; i++)
	{
		v2.push_back(i);
	}

	v3.resize(min(v1.size(), v2.size()));

	vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());

	printVectorInt(v3);
	for_each(v3.begin(), itEnd, print);
	cout << endl;
}

int main() {


	test01();

	return 0;
}

89、两个集合的并集set_union

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include"common.h"
// 集合的并集

void print(int v) {
	cout << v << " ";
}

void test01() {
	vector<int> v1;
	vector<int> v2;

	vector<int> v3;

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	for (int i = 2; i < 15; i++)
	{
		v2.push_back(i);
	}

	v3.resize(v1.size()+ v2.size());
	
	vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());

	printVectorInt(v3);
	for_each(v3.begin(), itEnd, print);
	cout << endl;
}

int main() {


	test01();

	return 0;
}

90、常用集合算法set_diffrence

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include"common.h"
// 集合的交集

void print(int v) {
	cout << v << " ";
}

void test01() {
	vector<int> v1;
	vector<int> v2;

	vector<int> v3;

	for (int i = 0; i < 10; i++)
	{
		v1.push_back(i);
	}

	for (int i = 2; i < 15; i++)
	{
		v2.push_back(i);
	}

	v3.resize(max(v1.size(), v2.size()));

	vector<int>::iterator itEnd = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());

	printVectorInt(v1);
	printVectorInt(v2);
	printVectorInt(v3);
	for_each(v3.begin(), itEnd, print);
	cout << endl;
}

int main() {

	test01();

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值