大綱
- 1 模板
- 1.1 模板的概念
- 1.2 函式的模板
- 1.2.1 函式的模板語法
- 1.2.2 函式模板注意事項
- 1.2.3 函式模板案例
- 1.2.4 普通函式與函式模板的區別
- 1.2.5 普通函式與函式模板的呼叫規則
- 1.2.6 模板的局限性
- 1.3 類模板
- 1.3.1 類模板語法
- 1.3.2 類模板與函式模板區別
- 1.3.3 類模板中成員函式創建時機
- 1.3.4 類模板物件做函式引數
- 1.3.5 類模板與繼承
- 1.3.6 類模板成員函式類外實作
- 1.3.7 類模板分檔案撰寫
- 1.3.8 類模板與友元
- 1.3.9 類模板案例 — 通用陣列
- 2 STL初識
- 2.1 STL的誕生
- 2.2 STL基本概念
- 2.3 STL六大組件
- 2.4 STL中容器、演算法、迭代器
- 2.5 容器、演算法、迭代器初識
- 2.5.1 vector存放內置資料型別
- 2.5.2 vector存放自定義資料型別
- 2.5.3 vector容器嵌套容器
- 3 STL-常用容器
- 3.1 string容器
- 3.1.1 string基本概念
- 3.1.2 string建構式
- 3.1.3 string賦值操作
- 3.1.4 string字串拼接
- 3.1.5 string查找與替換
- 3.1.6 string字串比較
- 3.1.7 string字符存取
- 3.1.8 string插入與洗掉
- 3.1.9 string子串
- 3.2 vector容器
- 3.2.1 vector基本概念
- 3.2.2 vector建構式
- 3.2.3 vector賦值操作
- 3.2.4 vector容量和大小
- 3.2.5 vector插入與洗掉
- 3.2.6 vector資料存取
- 3.2.7 vector互換容器
- 3.2.8 vector預留空間
- 3.3 deque容器
- 3.3.1 deque容器基本概念
- 3.3.2 deque建構式
- 3.3.3 deque賦值操作
- 3.3.4 deque大小操作
- 3.3.5 deque插入與洗掉
- 3.3.6 deque資料存取
- 3.3.7 deque排序
- 3.4 案例 -- 評委打分
- 3.4.1 案例描述
- 3.4.2 實作步驟
- 3.4.3 案例實作
- 3.5 stack容器
- 3.5.1 stack基本概念
- 3.5.2 stack常用介面
- 3.6 queue容器
- 3.6.1 queue基本概念
- 3.6.2 queue常用介面
- 3.7 list容器
- 3.7.1 list基本概念
- 3.7.2 list建構式
- 3.7.3 list賦值與交換
- 3.7.4 list大小操作
- 3.7.5 list插入與洗掉
- 3.7.6 list資料存取
- 3.7.7 list反轉與排序
- 3.7.8 list排序案例
- 3.8 set/multiset容器
- 3.8.1 set基本概念
- 3.8.2 set構造和賦值
- 3.8.3 set大小和交換
- 3.8.4 set插入與洗掉
- 3.8.5 set查找和統計
- 3.8.6 set和multiset區別
- 3.8.7 pair對組創建
- 3.8.8 set容器排序
- 3.9 map/multimap容器
- 3.9.1 map基本概念
- 3.9.2 map構造和賦值
- 3.9.3 map大小和交換
- 3.9.4 map插入與洗掉
- 3.9.5 map查找和統計
- 3.9.6 map容器排序
- 3.10 案例 -- 員工分組
- 3.10.1 案例描述
- 3.10.2 實作步驟
- 3.10.3 案例實作
- 4 STL-函式物件
- 4.1 函式物件
- 4.1.1 函式物件概念
- 4.1.2 函式物件使用
- 4.2 謂詞
- 4.2.1 謂詞概念
- 4.2.1 一元謂詞
- 4.2.1 二元謂詞
- 4.3 內建函式物件
- 4.3.1 內建函式物件意義
- 4.3.2 算術仿函式
- 4.3.3 關系仿函式
- 4.3.4 邏輯仿函式
- 5 STL-常用演算法
- 5.1 常用遍歷演算法
- 5.1.1 for_each
- 5.1.2 transform
- 5.2 常用查找演算法
- 5.2.1 find
- 5.2.2 find_if
- 5.2.3 adjacent_find
- 5.2.4 binary_search
- 5.2.5 count
- 5.2.6 count_find
- 5.3 常用排序演算法
- 5.3.1 sort
- 5.3.2 random_shuffle
- 5.3.3 merge
- 5.3.4 reverse
- 5.4 常用拷貝和替換演算法
- 5.4.1 copy
- 5.4.2 replace
- 5.4.3 replace_if
- 5.4.4 swap
- 5.5 常用算術生成演算法
- 5.5.1 accumulate
- 5.5.2 fill
- 5.6 常用集合演算法
- 5.6.1 set_intersection
- 5.6.2 set_union
- 5.6.3 set_difference
1 模板
1.1 模板的概念

1.2 函式的模板

1.2.1 函式的模板語法

//函式模板
template<typename T>
void mySwap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
void test() {
int a = 1;
int b = 2;
string c = "c";
string d = "d";
mySwap(a, b);
//mySwap<int>(a, b); //顯示指定型別
mySwap(c, d);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
cout << "d = " << d << endl;
}
int main() {
test();
return 0;
}
1.2.2 函式模板注意事項

1.2.3 函式模板案例

//排序
//交換模板
template<class T>
void mySwap(T &a, T &b) {
T temp = a;
a = b;
b = temp;
}
//排序模板
template<class T>
void mySort(T arr,int len) {
for (int i = 0; i < len; i++) {
int max = i;
for (int j = i + 1; j < len; j++) {
if (arr[j] > arr[max]) {
max = j;
}
}
if (max != i) {
mySwap(arr[max], arr[i]);
}
}
}
//列印模板
template<class T>
void myPrint(T arr,int len) {
for (int i = 0; i < len; i++) {
cout << arr[i] ;
}
cout << endl;
}
void test() {
int arr1[] = { 1,5,9,0,2,8,4 };
char arr2[] = "asdwfg";
int len1;
int len2;
len1 = sizeof(arr1) / sizeof(arr1[0]);
len2 = sizeof(arr2) / sizeof(arr2[0]);
mySort(arr1, len1);
myPrint(arr1, len1);
mySort(arr2,len2);
myPrint(arr2, len2);
}
int main() {
test();
return 0;
}
1.2.4 普通函式與函式模板的區別

- 建議使用顯示指定型別的方式呼叫函式模板
//mySwap(a,b);
mySwap<int>(a, b);
1.2.5 普通函式與函式模板的呼叫規則

//強制呼叫函式模板
mySwap<>(a, b);
1.2.6 模板的局限性
//類定義
class person {
public:
int m_age;
string m_name;
person(int age, string name) {
this->m_age = age;
this->m_name = name;
}
};
//普通函式模板
template<class T>
bool myCompare(T &a, T &b) {
if (a == b) {
return true;
}
else {
return false;
}
}
//具體化模板
template<> bool myCompare(person &p1, person &p2) {
if (p1.m_age == p2.m_age&&p1.m_name == p2.m_name) {
return true;
}
else {
return false;
}
}
//列印
void myPrint(bool &ret) {
if (ret) {
cout << "相同" << endl;
}
else {
cout << "不同" << endl;
}
}
void test() {
person p1 = { 18,"Tom" };
person p2 = { 28,"Tom" };
bool ret1 = myCompare(p1, p2);
myPrint(ret1);
bool ret2 = myCompare(p1.m_name, p2.m_name);
myPrint(ret2);
}
int main() {
test();
return 0;
}
1.3 類模板
1.3.1 類模板語法

template<class nameType, class ageType>
class person{
public:
nameType m_name;
ageType m_age;
}
void test(){
person<string,int> p1("Tom",18);
}
1.3.2 類模板與函式模板區別

template<class nameType, class ageType = int>
class person{
public:
nameType m_name;
ageType m_age;
}
void test(){
person<string> p1("Tom",18);
}
1.3.3 類模板中成員函式創建時機

1.3.4 類模板物件做函式引數

//查看模板引數型別名
cout << typeid(T).name() << endl;
template<class T1, class T2>
class person {
public:
T1 m_age;
T2 m_name;
person(T1 age, T2 name) {
this->m_age = age;
this->m_name = name;
}
void person_print() {
cout << this->m_age << endl;
cout << this->m_name << endl;
}
};
//指定傳入型別
void myPrint01(person<int, string> &p1) {
p1.person_print();
}
void test01() {
person<int, string> p1(18, "Tom");
myPrint01(p1);
}
//引數模板化
template<class T1,class T2>
void myPrint02(person<T1, T2> &p2) {
p2.person_print();
cout << typeid(T1).name() << endl;
}
void test02() {
person<int, string> p2(28, "Jack");
myPrint02(p2);
}
//整個類模板化
template<class T>
void myPrint03(T &p3) {
p3.person_print();
cout << typeid(T).name() << endl;
}
void test03() {
person<int, string> p3(38, "John");
myPrint03(p3);
}
int main() {
test01();
test02();
test03();
return 0;
}
1.3.5 類模板與繼承

//父類
template<class T>
class Base {
public:
T m;
};
//子類
template<class T1,class T2>
class Son :public Base<T1> {
public:
T2 n;
Son() {
cout << typeid(T1).name() << endl;
cout << typeid(T2).name() << endl;
}
};
void test() {
Son<int, string> s1;
}
int main() {
test();
return 0;
}
1.3.6 類模板成員函式類外實作
template<class T1, class T2>
class person {
public:
T1 m_age;
T2 m_name;
person(T1 age, T2 name);
void person_print();
};
//建構式的類外實作
template<class T1, class T2>
person<T1, T2>::person(T1 age, T2 name) {
this->m_age = age;
this->m_name = name;
}
//成員函式的類外實作
template<class T1, class T2>
void person<T1, T2>::person_print() {
cout << this->m_age << endl;
cout << this->m_name << endl;
}
void test() {
person<int, string> p1(18,"Tom");
p1.person_print();
}
int main() {
test();
return 0;
}
1.3.7 類模板分檔案撰寫

- tree.hpp
#pragma once
#include<iostream>
#include<string>
using namespace std;
template<class T1, class T2>
class tree {
public:
T1 m_age;
T2 m_name;
tree(T1 age, T2 name);
void tree_print();
};
//建構式的類外實作
template<class T1, class T2>
tree<T1, T2>::tree(T1 age, T2 name) {
this->m_age = age;
this->m_name = name;
}
//成員函式的類外實作
template<class T1, class T2>
void tree<T1, T2>::tree_print() {
cout << this->m_age << endl;
cout << this->m_name << endl;
}
- main.cpp
#include"tree.hpp"
void test() {
tree<int, string> t1(180,"銀杏");
t1.tree_print();
}
int main() {
test();
return 0;
}
1.3.8 類模板與友元

template<class T1, class T2>
class person;
//提前宣告全域函式
template<class T1, class T2>
void person_print2(person<T1, T2> p) {
cout << " 類外實作 " << p.m_name << endl;
}
template<class T1, class T2>
class person {
//全域函式類內實作
friend void person_print1(person<T1,T2> p) {
cout << " 類內實作 " << p.m_name << endl;
}
//全域函式類外實作
friend void person_print2<>(person<T1, T2> p);
public:
person(T1 age, T2 name) {
this->m_age = age;
this->m_name = name;
}
private:
T1 m_age;
T2 m_name;
};
void test() {
//類內
person<int, string> p1(18,"Tom");
person_print1(p1);
//類外
person<int, string> p2(28, "Rose");
person_print2(p2);
}
int main() {
test();
return 0;
}
1.3.9 類模板案例 — 通用陣列

- main.cpp
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
};
void printArray(myArray<person> & arr) {
for (int i = 0; i < arr.get_size(); i++) {
cout << arr[i].m_name << "\n" << arr[i].m_age << endl;
}
}
void test() {
myArray<person> arr1(3);
person p1("A", 18);
person p2("B", 28);
person p3("C", 38);
arr1.push_back(p1);
arr1.push_back(p2);
arr1.push_back(p3);
printArray(arr1);
}
int main() {
test();
return 0;
}
- myArray.hpp
#pragma once
#include<iostream>
#include<string>
using namespace std;
template<class T>
class myArray {
public:
myArray(int capacity) {
//cout << "有參構造" << endl;
this->m_Capacity = capacity;
this->m_size = 0;
this->pAddress = new T[this->m_Capacity];
}
myArray(const myArray & arr) {
//cout << "拷貝構造" << endl;
this->m_Capacity = arr.m_Capacity;
this->m_size = arr.m_size;
//this->pAddress = arr.pAddress; //淺拷貝 堆區資料會重復釋放
this->pAddress = new T[arr.m_Capacity]; //深拷貝
for (int i = 0; i < this->m_size; i++) {
this->pAddress[i] = arr.pAddress[i];
}
}
myArray & operator=(const myArray & arr) {
//cout << "operator=構造" << endl;
if (this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL;
this->m_Capacity = 0;
this->m_size = 0;
}
this->m_Capacity = arr.m_Capacity;
this->m_size = arr.m_size;
this->pAddress = new T[arr.m_Capacity];
for (int i = 0; i < this->m_size; i++) {
this->pAddress[i] = arr.pAddress[i];
}
return *this;
}
//尾插法
void push_back(const T & val) {
//判斷是否有容量
if (this->m_size == this->m_Capacity) {
return;
}
//插入資料
this->pAddress[this->m_size] = val;
//更新陣列大小
this->m_size++;
}
//尾刪法
void pop_back() {
//判斷是否有資料
if (this->m_size == 0) {
return;
}
//讓用戶訪問不到該元素,邏輯洗掉
this->m_size--;
}
//下標訪問資料
T& operator[](int index) {
return this->pAddress[index];
}
//獲取陣列容量
int get_Capacity() {
return this->m_Capacity;
}
//獲取陣列大小
int get_size() {
return this->m_size;
}
~myArray() {
//cout << "解構式" << endl;
if (this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL;
}
}
private:
//堆區陣列指標
T * pAddress;
//陣列容量
int m_Capacity;
//陣列大小
int m_size;
};
2 STL初識
2.1 STL的誕生

2.2 STL基本概念

2.3 STL六大組件

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




2.5 容器、演算法、迭代器初識
2.5.1 vector存放內置資料型別

#include<vector>
#include<algorithm> //標準演算法頭檔案
void myPrint(int val) {
cout << val << endl;
}
void test() {
vector<int> v1;
//尾插資料
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
//第一種遍歷
vector<int>::iterator itBegin = v1.begin(); //起始迭代器 指向容器中第一個元素
vector<int>::iterator itEnd = v1.end(); //結束迭代器 指向容器中最后一個元素的下一個位置
while (itBegin != itEnd) {
myPrint(*itBegin);
itBegin++;
}
//第二種遍歷
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++) {
myPrint(*it);
}
//第三種遍歷 利用STL提供的遍歷演算法
for_each(v1.begin(), v1.end(), myPrint);
}
int main() {
test();
return 0;
}
2.5.2 vector存放自定義資料型別

#include<vector>
class person {
public:
string m_name;
int m_age;
person(string name,int age) {
this->m_name = name;
this->m_age = age;
}
};
void myPrint(person &p) {
cout << p.m_name << "\t" << p.m_age << endl;
}
void test() {
//自定義資料型別
vector<person> p;
person p1("張三", 18);
person p2("李四", 28);
person p3("王五", 38);
p.push_back(p1);
p.push_back(p2);
p.push_back(p3);
for (vector<person>::iterator it1 = p.begin(); it1 != p.end(); it1++) {
myPrint(*it1);
//cout << it1->m_name << "\t" << it1->m_age << endl;
}
//自定義資料指標
vector<person*> v;
person p4("張三", 19);
person p5("李四", 29);
person p6("王五", 39);
v.push_back(&p4);
v.push_back(&p5);
v.push_back(&p6);
for (vector<person*>::iterator it2 = v.begin(); it2 != v.end(); it2++) {
myPrint(**it2);
//cout << (*it2)->m_name << "\t" << (*it2)->m_age << endl;
}
}
int main() {
test();
return 0;
}
2.5.3 vector容器嵌套容器

#include<vector>
void test() {
vector<vector<int>> v;
vector<int> v1;
vector<int> v2;
vector<int> v3;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
v2.push_back(i * 10 + 1);
v3.push_back((i + 2) * 7);
}
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
for (vector<vector<int>>::iterator it1 = v.begin(); it1 != v.end(); it1++) {
//(*it1) -- 容器 vector<int>
for (vector<int>::iterator it2 = (*it1).begin(); (it2) != (*it1).end(); it2++) {
cout << *it2 << "\t";
}
cout << endl;
}
}
int main() {
test();
return 0;
}
3 STL-常用容器
3.1 string容器
3.1.1 string基本概念

3.1.2 string建構式

void test() {
//string()
string s1;
//string(const char* s)
const char* str = "hello world";
string s2(str);
//string(const string& str)
string s3(s2);
//string(int n,char c)
string s4(5, 'a');
cout << s1 << endl
<< s2 << endl
<< s3 << endl
<< s4 << endl;
}
int main() {
test();
return 0;
}
3.1.3 string賦值操作

void test() {
string str1;
str1.assign("hello world");
cout << str1 << endl;
//把前n個字符賦值
string str2;
str2.assign("hello world", 8);
cout << str2 << endl;
}
int main() {
test();
return 0;
}
3.1.4 string字串拼接

void test() {
string str1 = "~$root:";
str1 += "zxy";
cout << str1 << endl;
string str2 = ":";
str1 += str2;
cout << str1 << endl;
//截取字串的前 n 個添加
str1.append("sudo apt-get install ros-kinetic-moveit",10);
cout << str1 << endl;
//截取字串的第 m 到第 n 個添加
string str3 = "sudo apt-get install ros-kinetic-moveit";
str1.append(str3, 10,-1);
cout << str1 << endl;
}
int main() {
test();
return 0;
}
3.1.5 string查找與替換

void test() {
string str = "abcdab";
//如果找到 回傳字串首位置,未找到回傳值-1
int pos;
//find 從左往右第一次出現的位置
pos = str.find("ab");
cout << "find : " << pos << endl;
//rfind 從右往左第一次出現的位置
pos = str.rfind("ab");
cout << "rfind: " << pos << endl;
//str.replace(替換的起始位置<從0開始>, 替換的個數, 替換后的內容);
string str2 = " ab ** ab ";
str.replace(2, 2, str2);
cout << str << endl;
}
int main() {
test();
return 0;
}
3.1.6 string字串比較

string str1 = "abc";
string str2 = "bbc";
int ret = str1.compare(str2);
3.1.7 string字符存取

void test() {
string str1 = "abcdefg";
//通過[]、at訪問單個字符
for (int i = 0; i < str1.size(); i++) {
cout << str1[i] ;
cout << str1.at(i) ;
}
//通過[]、at修改單個字符
for (int i = 0; i < str1.size(); i++) {
//str1[i] = 'x';
str1.at(i) = 'x';
}
cout << str1 << endl;
}
int main() {
test();
return 0;
}
3.1.8 string插入與洗掉

void test() {
string str1 = "abcde";
string str2 = "123";
//從第2號位置插入字串str2<插入字串后的首位置為2>
str1.insert(2, str2);
cout << str1 << endl;
//洗掉第2號位置起的3個字符
str1.erase(2, 3);
cout << str1 << endl;
}
int main() {
test();
return 0;
}
3.1.9 string子串

void test() {
string email = "zhangsan@qq.com";
int pos = email.find('@');
//從第0號位置開始,截取pos個字符
string sub_name = email.substr(0, pos);
cout << sub_name << endl;
}
int main() {
test();
return 0;
}
3.2 vector容器
3.2.1 vector基本概念


3.2.2 vector建構式

#include<vector>
void printVector(vector<int> &v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " " ;
}
cout << endl;
}
void test() {
//默認無參構造
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i * 6 + 8);
}
printVector(v1);
//通過區間構造
vector<int> v2(v1.begin(), v1.end());
printVector(v2);
//通過 n 個 elem 構造(元素個數,元素值)
vector<int> v3(10,100);
printVector(v3);
//通過拷貝構造
vector<int> v4(v3);
printVector(v4);
}
int main() {
test();
return 0;
}
3.2.3 vector賦值操作

vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i * 6 + 8);
}
vector<int> v2;
v2 = v1;
vector<int> v3;
v3.assign(v1.begin(), v1.end());
vector<int> v4;
v4.assign(10,100);
3.2.4 vector容量和大小

#include<vector>
void printVector(vector<int> &v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " " ;
}
cout << endl;
cout << "v1的容量為: " << v.capacity() << endl;
cout << "v1的大小為: " << v.size() << endl;
}
void test() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i * 9 + 8);
}
//判斷是否為空
if (v1.empty()) {
cout << "v1 is empty" << endl;
}
else {
printVector(v1);
//重新指定容器大小,(容器大小,填充值(默認為0))
v1.resize(15,100);
printVector(v1);
v1.resize(5);
printVector(v1);
}
}
int main() {
test();
return 0;
}
3.2.5 vector插入與洗掉

#include<vector>
void printVector(vector<int> &v) {
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test() {
vector<int> v1;
//尾插
for (int i = 0; i < 10; i++) {
v1.push_back(i * 8 + 8);
}
printVector(v1);
//尾刪
v1.pop_back();
printVector(v1);
//insert(位置迭代器,插入個數(默認1個),插入值)
v1.insert(v1.begin() + 1, 2, 99);
printVector(v1);
//洗掉
v1.erase(v1.begin() + 2);
printVector(v1);
//清空
v1.clear();
printVector(v1);
}
int main() {
test();
return 0;
}
3.2.6 vector資料存取

#include<vector>
void test() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i * 11 + 45);
}
//利用[]訪問陣列元素
for (int i = 0; i < v1.size(); i++) {
cout << v1[i] << " ";
}
cout << endl;
//利用at訪問陣列元素
for (int i = 0; i < v1.size(); i++) {
cout << v1.at(i) << " ";
}
cout << endl;
//獲取第一個元素
cout << "第一個元素 : " << v1.front() << endl;
//獲取最后一個元素
cout << "最后一個元素: " << v1.back() << endl;
}
int main() {
test();
return 0;
}
3.2.7 vector互換容器

#include<vector>
void printVector(vector<int> &v,string index) {
cout << index << ": ";
for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
cout << *it << " " ;
}
cout << endl;
}
void test() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i * 13 + 24);
}
printVector(v1,"v1");
vector<int> v2;
for (int i = 0; i < 10; i++) {
v2.push_back(i * 56 + 2);
}
printVector(v2, "v2");
//容器元素互換
v1.swap(v2);
printVector(v1, "v1");
printVector(v2, "v2");
//收縮記憶體
vector<int> v3;
for (int i = 0; i < 1000; i++) {
v3.push_back(i * 13 + 24);
}
cout << "v3的容量為: " << v3.capacity() << endl;
cout << "v3的大小為: " << v3.size() << endl;
v3.resize(10);
cout << "v3的容量為: " << v3.capacity() << endl;
cout << "v3的大小為: " << v3.size() << endl;
//vector<int>(v3)為匿名物件,系統自動回收
vector<int>(v3).swap(v3);
cout << "v3的容量為: " << v3.capacity() << endl;
cout << "v3的大小為: " << v3.size() << endl;
}
int main() {
test();
return 0;
}
3.2.8 vector預留空間

#include<vector>
void test() {
vector<int> v1;
int num = 0;
int * p = NULL;
for (int i = 0; i < 1000; i++) {
v1.push_back(i);
//如果重新開辟了記一次
if (p != &v1[0]) {
p = &v1[0];
num++;
}
}
cout << "v1開辟記憶體空間次數: " << num << endl;
vector<int> v2;
v2.reserve(1000);
int re_num = 0;
int * re_p = NULL;
for (int i = 0; i < 1000; i++) {
v2.push_back(i);
//如果重新開辟了記一次
if (re_p != &v2[0]) {
re_p = &v2[0];
re_num++;
}
}
cout << "v2開辟記憶體空間次數: " << re_num << endl;
}
int main() {
test();
return 0;
}
3.3 deque容器
3.3.1 deque容器基本概念


3.3.2 deque建構式

#include<deque>
void printDeque(const deque<int>& d) {
for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
//*it = 100; //常量需要使用const_iterator
cout << *it << " ";
}
cout << endl;
}
void test() {
deque<int> d1;
for (int i = 0; i < 10; i++) {
d1.push_back(i * 11);
d1.push_front(i * 10);
}
printDeque(d1);
deque<int> d2(d1.begin() + 1, d1.end()-1);
printDeque(d2);
deque<int> d3(20,99);
printDeque(d3);
deque<int> d4(d3);
printDeque(d4);
}
int main() {
test();
return 0;
}
3.3.3 deque賦值操作

3.3.4 deque大小操作

3.3.5 deque插入與洗掉

deque<int> d1;
deque<int> d2;
//在指定位置插入區間值
d1.insert(d1.begin(),d2.begin(),d2.end())
3.3.6 deque資料存取

3.3.7 deque排序

#include<deque>
#include<algorithm>
void printDeque(const deque<int>& d) {
for (int i = 0; i < d.size(); i++) {
cout << d[i] << " ";
}
cout << endl;
}
void test() {
deque<int> d1;
for (int i = 0; i < 10; i++) {
d1.push_back(i * 11);
d1.push_front(i * 10);
}
printDeque(d1);
//默認由小到大排序
//支持隨機訪問的迭代器的容器,都可以利用sort進行排序
sort(d1.begin(), d1.end());
printDeque(d1);
}
int main() {
test();
return 0;
}
3.4 案例 – 評委打分
3.4.1 案例描述

3.4.2 實作步驟

3.4.3 案例實作
#include<vector>
#include<algorithm>
#include<deque>
#include<ctime>
class player {
public:
int m_id; //編號
int m_score; //平均分
deque<int> score; //所有評分
player(int m_id,int m_score){
this->m_id = m_id;
this->m_score = m_score;
}
void printScore() {
for (int i = 0; i < 10; i++) {
cout << this->score[i] << " ";
}
cout << endl;
}
};
void pushPlayer(vector<player> &play) {
for (int i = 0; i < 5; i++) {
player p(i + 1, 0);
play.push_back(p);
}
}
void test() {
vector<player> play;
play.reserve(5);
//選手參加
pushPlayer(play);
srand((unsigned int)time(NULL));
for (vector<player>::iterator it = play.begin(); it != play.end(); it++) {
for (int i = 0; i < 10; i++) {
//打分
//rand() % 41 為0 ~ 40
int score_rand = rand() % 41 + 60;
it->score.push_back(score_rand);
}
//對成績進行排序
sort(it->score.begin(), it->score.end());
it->printScore();
//去掉最高分和最低分
it->score.pop_back();
it->score.pop_front();
//求平均分
int sum = 0;
for (int i = 0; i < it->score.size(); i++) {
sum += it->score[i];
}
int avg = sum / it->score.size();
it->m_score = avg;
cout << "id: " << it->m_id << " 成績為: " << it->m_score << endl << endl;
}
}
int main() {
test();
return 0;
}
3.5 stack容器
3.5.1 stack基本概念


- 堆疊不允許有遍歷行為
- 堆疊可以判斷容器是否為空 empty()
- 堆疊可以回傳元素個數 size()
3.5.2 stack常用介面

#include<stack>
void test() {
stack<int> s;
for (int i = 0; i < 5; i++) {
s.push(i * 4 + 1);
}
cout << "出堆疊前堆疊的大小: " << s.size() << endl;
while (!s.empty()) {
//查看堆疊頂元素
cout << s.top() << endl;
//出堆疊
s.pop();
}
cout << "出堆疊后堆疊的大小: " << s.size() << endl;
}
int main() {
test();
return 0;
}
3.6 queue容器
3.6.1 queue基本概念

- 佇列不允許有遍歷行為
- 佇列可以判斷容器是否為空 empty()
- 佇列可以回傳元素個數 size()
3.6.2 queue常用介面

#include<queue>
void test() {
queue<int> q;
for (int i = 0; i < 5; i++) {
q.push(i * 7 + 2);
}
while (!q.empty()) {
cout << "佇列的隊頭: " << q.front() << endl;
cout << "佇列的隊尾: " << q.back() << endl;
q.pop();
}
cout << "" << q.size() << endl;
}
int main() {
test();
return 0;
}
3.7 list容器
3.7.1 list基本概念


- 鏈表可以在任意位置進行快速的插入或洗掉元素
- 鏈表動態分配存盤,不會造成記憶體浪費
- 鏈表遍歷速度慢
- 鏈表占用空間大

- List鏈表中,插入和洗掉元素不會造成原有list迭代器的失效,而vector是不成立的(記憶體滿了之后另開一處空間進行存盤)
3.7.2 list建構式

#include<list>
void printList(const list<int> &L) {
for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test() {
//默認構造
list<int> L1;
for (int i = 0; i < 10; i++) {
L1.push_back(i * 2 + 3);
}
printList(L1);
//區間構造
list<int> L2(L1.begin(), L1.end());
printList(L2);
//拷貝構造
list<int> L3(L2);
printList(L3);
}
int main() {
test();
return 0;
}
3.7.3 list賦值與交換

3.7.4 list大小操作

3.7.5 list插入與洗掉

#include<list>
void printList(const list<int> &L) {
for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test() {
list<int> L1;
for (int i = 0; i < 10; i++) {
L1.push_back(i % 2 );
}
printList(L1);
//insert插入
L1.insert(++L1.begin(), 2, 3);
printList(L1);
//erase洗掉
L1.erase(++L1.begin());
printList(L1);
//remove洗掉,洗掉容器中所有指定的元素值
L1.remove(0);
printList(L1);
}
int main() {
test();
return 0;
}
3.7.6 list資料存取

3.7.7 list反轉與排序

#include<list>
void printList(const list<int> &L) {
for (list<int>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
//排序的判斷函式
bool myCompare(int v1, int v2) {
return v1 > v2;
}
void test() {
list<int> L1;
for (int i = 0; i < 10; i++) {
L1.push_back((i % 2) * 6 + i);
}
printList(L1);
L1.reverse();
cout << "反轉后的鏈表: " << endl;
printList(L1);
L1.sort();//默認升序
cout << "排序后的鏈表: " << endl;
printList(L1);
//降序排列操作
L1.sort(myCompare);
printList(L1);
//所有不支持隨機訪問迭代器的容器,不可以用標準演算法(eg:sort())(全域函式)
//不支持隨機訪問迭代器的容器,內部會提供對應的演算法(成員函式)
}
int main() {
test();
return 0;
}
3.7.8 list排序案例

#include<list>
#include<ctime>
class person {
public:
string m_name;
int m_age;
int m_height;
person() {};
person(string name, int age,int height) {
this->m_name = name;
this->m_age = age;
this->m_height = height;
}
};
//創建物件
void creatPerson(list<person> &L,int num) {
string nameSeed = "ABCDEFGHIJK";
for (int i = 0; i < num; i++) {
person p;
p.m_name += nameSeed[i];
p.m_age = 20 + rand() % 5;
p.m_height = 180 + rand() % 10;
L.push_back(p);
}
}
//列印資訊
void printList(const list<person> &L) {
for (list<person>::const_iterator it = L.begin(); it != L.end(); it++) {
cout << "姓名: " << (*it).m_name << " 年齡: " << (*it).m_age << " 身高: " << (*it).m_height << endl;
}
}
//排序規則
bool myCompare(person &p1,person &p2) {
//如果年齡不同,進行升序排列
if (p1.m_age != p2.m_age) {
return p1.m_age < p2.m_age;
}
//如果年齡相同,對身高進行降序排列
else {
return p1.m_height > p2.m_height;
}
}
void test() {
srand((unsigned int)time(NULL));
list<person> L1;
creatPerson(L1, 10);
cout << "排序前:" << endl;
printList(L1);
cout << "排序后:" << endl;
L1.sort(myCompare);
printList(L1);
}
int main() {
test();
return 0;
}
3.8 set/multiset容器
3.8.1 set基本概念

3.8.2 set構造和賦值

#include<set>
#include<ctime>
void printSet(const set<int> &s) {
for (set<int>::const_iterator it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void printSet(const multiset<int> &s) {
for (multiset<int>::const_iterator it = s.begin(); it != s.end(); it++) {
cout << *it << " ";
}
cout << endl;
}
void test() {
srand((unsigned)time(NULL));
set<int> s1;
for (int i = 0; i < 20; i++) {
//插入資料只能用insert
s1.insert(rand() % 10);
}
//set容器不允許重復的值插入
printSet(s1);
multiset<int> s2;
for (int i = 0; i < 20; i++) {
s2.insert(rand() % 10);
}
//multiset容器允許重復的值插入
printSet(s2);
}
int main() {
test();
return 0;
}
3.8.3 set大小和交換

3.8.4 set插入與洗掉

3.8.5 set查找和統計

#include<set>
#include<ctime>
void test() {
srand((unsigned)time(NULL));
set<int> s1;
for (int i = 0; i < 20; i++) {
s1.insert(rand() % 10);
}
//找到元素回傳其迭代器位置,沒找到回傳set.end()位置
set<int>::iterator pos = s1.find(5);
if (pos != s1.end()) {
cout << "找到了" << endl;
}
else {
cout << "沒有找到" << endl;
}
multiset<int> s2;
for (int i = 0; i < 20; i++) {
s2.insert(rand() % 10);
}
//回傳元素的個數
//對于set而言結果只有0或1
int num = s2.count(5);
cout << "元素個數為: " << num << endl;
}
int main() {
test();
return 0;
}
3.8.6 set和multiset區別

#include<set>
#include<ctime>
void test() {
srand((unsigned)time(NULL));
set<int> s1;
for (int i = 0; i < 10; i++) {
pair<set<int>::iterator, bool> ret = s1.insert(rand() % 10);
if (ret.second) {
cout << "資料插入成功 " << *ret.first << endl;
}
else {
cout << "資料插入失敗 " << *ret.first << endl;
}
}
multiset<int> s2;
for (int i = 0; i < 20; i++) {
s2.insert(rand() % 10);
}
}
int main() {
test();
return 0;
}
3.8.7 pair對組創建

void test() {
//第一種
pair<int, string> p1(1, "a");
cout << p1.first << " " << p1.second << endl;
//第二種
pair<int, string> p2 = make_pair(2, "b");
cout << p2.first << " " << p2.second << endl;
}
int main() {
test();
return 0;
}
3.8.8 set容器排序

#include<set>
class person {
public:
string m_name;
int m_age;
int m_height;
person() {};
person(string name, int age, int height) {
this->m_name = name;
this->m_age = age;
this->m_height = height;
}
};
//仿函式建立排序規則
class myCompare1 {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
class myCompare2 {
public:
bool operator()(const person &p1, const person &p2) {
if (p1.m_age == p2.m_age) {
return p1.m_height > p2.m_height;
}
else {
return p1.m_age > p2.m_age;
}
}
};
//創建物件
void creatPerson(int num, set<person, myCompare2> &s) {
string nameSeed = "ABCDEFGHIJKLMN";
for (int i = 0; i < num; i++) {
person p;
p.m_name += nameSeed[i];
p.m_age = 20 + rand() % 10;
p.m_height = 170 + rand() % 10;
s.insert(p);
}
}
//列印資訊
void printSet(set<person, myCompare2> &s) {
for (set<person, myCompare2>::iterator it = s.begin(); it != s.end(); it++) {
cout << " 姓名: " << (*it).m_name << " 年齡: " << (*it).m_age << " 身高: " << (*it).m_height << endl;
}
}
void test() {
//內置資料型別
//排序規則在插入資料之前
set<int, myCompare1> s1;
for (int i = 0; i < 20; i++) {
s1.insert(rand() % 10);
}
for (set<int, myCompare1>::iterator it = s1.begin(); it != s1.end(); it++) {
cout << *it << " ";
}
cout << endl;
//自定義資料型別
set<person, myCompare2> s2;
creatPerson(9, s2);
printSet(s2);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
3.9 map/multimap容器
3.9.1 map基本概念

3.9.2 map構造和賦值

#include<map>
void printMap(const map<int, int> &m) {
for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++) {
cout << it->first << "\t" << it->second << endl;
}
}
void test() {
map<int, int> m1;
for (int i = 0; i < 10; i++) {
//插入元素要使用對組pair
m1.insert(pair<int, int>(i, rand() % 41 + 60));
}
printMap(m1);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
3.9.3 map大小和交換

3.9.4 map插入與洗掉

#include<map>
void printMap(const map<int, int> &m) {
for (map<int, int>::const_iterator it = m.begin(); it != m.end(); it++) {
cout << it->first << "\t" << it->second << endl;
}
}
void test() {
map<int, int> m1;
//第一種
m1.insert(pair<int, int>(5, 10));
//第二種
m1.insert(make_pair(4, 20));
//第三種
m1.insert(map<int, int>::value_type(3, 30));
//第四種 不建議用于插入資料 可以用于讀取value值
//m1[2] = 40;
//cout << m1[3] << endl;
printMap(m1);
m1.erase(m1.begin());
printMap(m1);
//根據key值進行洗掉
m1.erase(4);
printMap(m1);
m1.erase(m1.begin(),m1.end());
printMap(m1);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
3.9.5 map查找和統計

3.9.6 map容器排序

#include<map>
class mapCompare {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
void printMap(const map<int, int, mapCompare> &m) {
for (map<int, int, mapCompare>::const_iterator it = m.begin(); it != m.end(); it++) {
cout << it->first << "\t" << it->second << endl;
}
}
void test() {
map<int, int, mapCompare> m1;
for (int i = 0; i < 10; i++) {
m1.insert(make_pair(i, rand() % 41 + 60));
}
printMap(m1);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
3.10 案例 – 員工分組
3.10.1 案例描述

3.10.2 實作步驟

3.10.3 案例實作
#include<vector>
#include<map>
#include<ctime>
#define CEHUA 0
#define MEISHU 1
#define YANFA 2
class stuff {
public:
string m_name;
int m_salary;
stuff() {};
stuff(string name, int salary) {
this->m_name = name;
this->m_salary = salary;
}
};
//員工資訊填入
void creatStuff(vector<stuff> &v) {
string nameSeed = "ABCDEFGHIJ";
for (int i = 0; i < 10; i++) {
stuff s;
s.m_name += nameSeed[i];
s.m_salary = 5000 + (rand() % 10) * 500;
v.push_back(s);
}
}
//列印員工資訊
void printStuff(const multimap<int, stuff> &m) {
cout << "------------------------" << endl;
cout << "策劃部門:" << endl;
multimap<int, stuff>::const_iterator pos = m.find(CEHUA);//策劃第一個人位置
int num = m.count(CEHUA);//策劃組人數
int index = 0;
for (; pos != m.end() && index < num; pos++, index++) {
cout << "姓名:" << pos->second.m_name << " 工資:" << pos->second.m_salary << endl;
}
cout << "------------------------" << endl;
cout << "美術部門:" << endl;
pos = m.find(MEISHU);
num = m.count(MEISHU);
index = 0;
for (; pos != m.end() && index < num; pos++, index++) {
cout << "姓名:" << pos->second.m_name << " 工資:" << pos->second.m_salary << endl;
}
cout << "------------------------" << endl;
cout << "研發部門:" << endl;
pos = m.find(YANFA);
num = m.count(YANFA);
index = 0;
for (; pos != m.end() && index < num; pos++, index++) {
cout << "姓名:" << pos->second.m_name << " 工資:" << pos->second.m_salary << endl;
}
}
//分配部門
void allocateDepart(const vector<stuff> &v, multimap<int, stuff> &m) {
for (vector<stuff>::const_iterator it = v.begin(); it != v.end(); it++) {
m.insert(make_pair(rand() % 3 , *it));
}
}
void test() {
//招聘員工
vector<stuff> v;
creatStuff(v);
//部門分配
multimap<int, stuff> m;
allocateDepart(v,m);
//列印資訊
printStuff(m);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
4 STL-函式物件
4.1 函式物件
4.1.1 函式物件概念

4.1.2 函式物件使用

class myPrint {
public:
//函式物件相較于普通函式,可以有自己的狀態,可以統計次數等
int count;
myPrint() {
this->count = 0;
}
void operator()(string text) {
cout << text << endl;
count++;
}
};
//函式物件可以作為引數傳遞
void print_test(myPrint &mP, string text) {
for (int i = 0; i < 5; i++) {
mP(text);
}
cout << mP.count << endl;
}
void test() {
//函式物件創建
myPrint mP;
string text = "hello world";
print_test(mP, text);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
4.2 謂詞
4.2.1 謂詞概念

- 謂詞體現在回傳型別,元數 體現在引數個數
4.2.1 一元謂詞
#include<vector>
#include<algorithm>
class score {
public:
bool operator()(int value) {
return value > 90;
}
};
void test() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(60 + rand() % 41);
}
//score()匿名函式物件
vector<int>::iterator pos = find_if(v.begin(), v.end(), score());
if (pos == v.end()) {
cout << "failed" << endl;
}
else {
cout << *pos << endl;
}
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
4.2.1 二元謂詞
#include<vector>
#include<algorithm>
class sortRules {
public:
bool operator()(int v1, int v2) {
return v1 > v2;
}
};
void printVector(vector<int> &v) {
for (vector<int>::iterator pos = v.begin(); pos != v.end(); pos++) {
cout << *pos << " ";
}
cout << endl;
}
void test() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(60 + rand() % 41);
}
cout << "修改規則前:" << endl;
sort(v.begin(), v.end());
printVector(v);
cout << "修改規則后: " << endl;
sort(v.begin(), v.end(), sortRules());
printVector(v);
}
int main() {
srand((unsigned)time(NULL));
test(); return 0;
}
4.3 內建函式物件
4.3.1 內建函式物件意義

4.3.2 算術仿函式

#include<functional>
void test() {
//取反仿函式
negate<int> n;
cout << n(10) << endl;
//取模仿函式
//二元仿函式也只定義一個資料型別,默認兩個相同
modulus<int> m;
cout << m(50, 7) << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
4.3.3 關系仿函式

#include<functional>
#include<vector>
#include<algorithm>
void test() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(60 + rand() % 41);
}
//greater<int>() 內建大于函式的匿名函式物件
sort(v.begin(), v.end(), greater<int>());
for (vector<int>::iterator pos = v.begin(); pos != v.end(); pos++) {
cout << *pos << " ";
}
cout << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
4.3.4 邏輯仿函式

#include<functional>
#include<vector>
#include<algorithm>
void test() {
vector<bool> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(rand() % 2);
}
vector<bool> v2;
v2.resize(v1.size());
//將容器v1的值搬運到v2 搬運前必須指定目標容器的大小 即:v2.resize(v1.size());
transform(v1.begin(), v1.end(), v2.begin(), logical_not<bool>());
for (vector<bool>::iterator pos = v2.begin(); pos != v2.end(); pos++) {
cout << *pos << " ";
}
cout << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5 STL-常用演算法

5.1 常用遍歷演算法

5.1.1 for_each

#include<vector>
#include<algorithm>
void printVector1(int val) {
cout << val << " ";
}
class printVector2 {
public:
void operator()(int val) {
cout << val << " ";
}
};
void test() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(rand() % 100);
}
//普通函式直接用函式名
cout << "普通函式:" << endl;
for_each(v.begin(), v.end(), printVector1);
cout << endl;
//仿函式用函式物件
cout << "仿函式:" << endl;
for_each(v.begin(), v.end(), printVector2());
cout << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.1.2 transform

#include<vector>
#include<algorithm>
void printVector(int val) {
cout << val << " ";
}
class transRules {
public:
int operator()(int val) {
return ++val;
}
};
void test() {
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
}
for_each(v1.begin(), v1.end(), printVector);
cout << endl;
vector<int> v2;
//目標容器 v2 必須提前設定大小
v2.resize(v1.size());
transform(v1.begin(),v1.end(),v2.begin(),transRules());
for_each(v2.begin(), v2.end(), printVector);
cout << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.2 常用查找演算法

5.2.1 find

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name,int age) {
this->m_name = name;
this->m_age = age;
}
//自定義資料型別 多載 == 號便于查找
bool operator==(const person &p) {
if (this->m_name == p.m_name&&this->m_age == p.m_age) {
return true;
}
else {
return false;
}
}
};
void test() {
vector<person> v;
string nameSeed = "ABCDEFGHIJK";
for (int i = 0; i < 5; i++) {
person p;
p.m_name += nameSeed[i];
//p.m_age = 25;
p.m_age = 23 + rand() % 3;
v.push_back(p);
}
person pFind("A",25);
vector<person>::iterator pos = find(v.begin(), v.end(), pFind);
if (pos == v.end()) {
cout << "未找到一樣的人" << endl;
}
else {
cout << "找到一樣的人" << endl;
}
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.2.2 find_if

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
};
class Greater {
public:
bool operator()(const person &p) {
if (p.m_age > 25) {
return true;
}
else {
return false;
}
}
};
void test() {
vector<person> v;
string nameSeed = "ABCDEFGHIJK";
for (int i = 0; i < 5; i++) {
person p;
p.m_name += nameSeed[i];
//p.m_age = 25;
p.m_age = 23 + rand() % 4;
v.push_back(p);
}
//自定義資料型別 用謂詞進行操作
vector<person>::iterator pos = find_if(v.begin(), v.end(), Greater());
if (pos == v.end()) {
cout << "未找到年齡大于25的人" << endl;
}
else {
cout << "找到年齡大于25的人" << endl;
}
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.2.3 adjacent_find

5.2.4 binary_search

- 必須是有序排布的容器(遞增或遞減)
5.2.5 count

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
//自定義資料型別 多載 == 進行操作
bool operator==(const person &p) {
if (this->m_age == p.m_age) {
return true;
}
else {
return false;
}
}
};
void test() {
vector<person> v;
string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
for (int i = 0; i < 10; i++) {
person p;
p.m_name = nameSeed[i];
p.m_age = rand() % 3 + 20;
v.push_back(p);
}
person pCount("Z", 21);
int num = count(v.begin(), v.end(), pCount);
cout << "年齡相同的人數:" << num << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.2.6 count_find

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
};
class PCount {
public:
bool operator()(const person &p) {
return p.m_age == 20;
}
};
void test() {
vector<person> v;
string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
for (int i = 0; i < 10; i++) {
person p;
p.m_name = nameSeed[i];
p.m_age = rand() % 3 + 20;
v.push_back(p);
}
int num = count_if(v.begin(), v.end(), PCount());
cout << "年齡相同的人數:" << num << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.3 常用排序演算法

5.3.1 sort

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
};
//排序規則
class sortRules {
public:
bool operator()(const person &p1, const person &p2) {
return p1.m_age > p2.m_age;
}
};
//列印函式
void printVector(const person &p) {
cout << "姓名:" << p.m_name << " 年齡:" << p.m_age << endl;
}
void test() {
vector<person> v;
string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
for (int i = 0; i < 10; i++) {
person p;
p.m_name = nameSeed[i];
p.m_age = rand() % 10 + 20;
v.push_back(p);
}
sort(v.begin(), v.end(), sortRules());
for_each(v.begin(), v.end(), printVector);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.3.2 random_shuffle

//亂數種子
srand((unsigned)time(NULL));
5.3.3 merge

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
};
//排序規則
class sortRules {
public:
bool operator()(const person &p1, const person &p2) {
return p1.m_age > p2.m_age;
}
};
void printVector(const person &p) {
cout << "姓名:" << p.m_name << " 年齡:" << p.m_age << endl;
}
void test() {
vector<person> v1;
vector<person> v2;
for (int i = 0; i < 10; i++) {
person p1;
p1.m_name = "A";
p1.m_age = 20 + rand() % 10;
v1.push_back(p1);
person p2;
p2.m_name = "B";
p2.m_age = 20 + rand() % 10;
v1.push_back(p2);
}
//兩個合并的容器必須是有序的排列,同時遞增或遞減
sort(v1.begin(), v1.end(), sortRules());
sort(v2.begin(), v2.end(), sortRules());
//需要給目標容器提取分配空間
vector<person> vTarget;
vTarget.resize(v1.size() + v2.size());
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin(), sortRules());
for_each(vTarget.begin(), vTarget.end(), printVector);
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.3.4 reverse

5.4 常用拷貝和替換演算法

5.4.1 copy

5.4.2 replace

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
bool operator==(const person &p) {
return(this->m_name == p.m_name&&this->m_age == p.m_age);
}
};
class printVector {
public:
void operator()(const person &p) {
cout << "姓名:" << p.m_name << " 年齡:" << p.m_age << endl;
}
};
void test() {
vector<person> v;
string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
for (int i = 0; i < 10; i++) {
person p;
p.m_name = nameSeed[0];
p.m_age = rand() % 3 + 20;
v.push_back(p);
}
cout << "替換前:" << endl;
for_each(v.begin(), v.end(), printVector());
person pOLD("A",22);
person pNEW("a", 22000);
replace(v.begin(), v.end(), pOLD, pNEW);
cout << "替換后:" << endl;
for_each(v.begin(), v.end(), printVector());
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.4.3 replace_if

#include<vector>
#include<algorithm>
class person {
public:
string m_name;
int m_age;
person() {};
person(string name, int age) {
this->m_name = name;
this->m_age = age;
}
//多載替換的 = 操作
void operator=(string name) {
this->m_name = name;
}
};
class printVector {
public:
void operator()(const person &p) {
cout << "姓名:" << p.m_name << " 年齡:" << p.m_age << endl;
}
};
//謂詞,替換條件
class replaceRules {
public:
bool operator()(const person&p) {
return p.m_age > 30;
}
};
void test() {
vector<person> v;
string nameSeed = "ABCDEFJHISAHJDJSAKLHFCVSDL";
for (int i = 0; i < 10; i++) {
person p;
p.m_name = nameSeed[i];
p.m_age = rand() % 10 + 25;
v.push_back(p);
}
cout << "替換前:" << endl;
for_each(v.begin(), v.end(), printVector());
replace_if(v.begin(), v.end(), replaceRules(), "大齡青年");
cout << "替換后:" << endl;
for_each(v.begin(), v.end(), printVector());
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.4.4 swap

5.5 常用算術生成演算法

5.5.1 accumulate

#include<numeric>
//第三個引數為 起始累加值
accumulate(v.begin(),v.end(),0);
5.5.2 fill

5.6 常用集合演算法

5.6.1 set_intersection

#include<vector>
#include<algorithm>
void printVector(int val) {
cout << val << " ";
}
void test() {
//取交集的兩個容器的元素必須是順序排列的
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
v2.push_back(i + 5);
}
vector<int> vTarget;
//提前分配目標容器大小
//目標容器的大小為 兩個容器中較小的容器大小
vTarget.resize(min(v1.size(), v2.size()));
//回傳的是一個迭代器
vector<int>::iterator it_end = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
cout << "交集為:" << endl;
//遍歷時使用it_end(系統回傳的值) 不使用vTarget.end()
for_each(vTarget.begin(), it_end, printVector);
cout << endl;
}
int main() {
srand((unsigned)time(NULL));
test();
return 0;
}
5.6.2 set_union

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

- 差集是所有元素除去交集部分后剩下的元素
- v1與v2的差集 和 v2對與v1的差集 結果不同
//目標容器大小
vTarget.resize(max(v1.size(), v2.size()));
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/385901.html
標籤:其他
上一篇:2021年浙江工商大學新生賽題解
下一篇:ARDUINO.
