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;
}