1. 函数适配器(bind2nd)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <set> // stl包
#include <algorithm> // 算法包
using namespace std;

int main() {
// std::cout << "算法包" << std::endl;

set<string, less<string>> setVar;
setVar.insert("AAAA");
setVar.insert("BBBB");
setVar.insert("CCCC");

for (set<string>::iterator iteratorVar = setVar.begin(); iteratorVar != setVar.end() ; iteratorVar++) {
cout << *iteratorVar << endl;
}

// find_if
// equal_to 比较用的
set<string, less<string>>::iterator iteratorResult =

// 解决尴尬的问题 equal_to 需要比较的 内容没有 使用 函数适配器 解决
// 现在的问题是: 没有办法把 CCCC 传递给 const _Tp& __y,就没法去比较
// find_if(setVar.begin(), setVar.end(), equal_to<string>("CCCC"), "CCCC");

// bind2nd作用是讲第二个参数注入func的第二个参数。
// 使用函数适配器后,就能够 CCCC 传递给了 const _Tp& __y,
// setVar.begin(), setVar.end() 会把这些元素取出来 const _Tp& __x
// x == y 的比较
find_if(setVar.begin(), setVar.end(), bind2nd(equal_to<string>(), "CCCC"));

if (iteratorResult != setVar.end()) {
cout << "查找到了" << endl;
} else {
cout << "没有查找到" << endl;
}

return 0;
}

2. for_each遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包
using namespace std;

class __F {
public:
void operator() (int __first) {
cout << "自定义一元谓词:" << __first << endl;
}
};

int main() {
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(), 10000);
vectorVar.insert(vectorVar.begin(), 20000);
vectorVar.insert(vectorVar.begin(), 30000);
vectorVar.insert(vectorVar.begin(), 40000);
vectorVar.insert(vectorVar.begin(), 50000);
vectorVar.insert(vectorVar.begin(), 60000);

for_each(vectorVar.begin(), vectorVar.end(), __F());

return 0;
}

3. transform变换操作符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包
using namespace std;

class __unary_op {
public:
int operator() (const int __first) {
return __first + 9; // 修改每个元素 +9
}
};

int main() {
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(), 10000);
vectorVar.insert(vectorVar.begin(), 20000);
vectorVar.insert(vectorVar.begin(), 30000);
vectorVar.insert(vectorVar.begin(), 40000);

// TODO 第一种方式 类似于 RxJava map 变化操作符 【不看API,直接看算法包源码 印象非常深刻的】
// 迭代器 result == 参数三
transform(vectorVar.begin(), vectorVar.end(), vectorVar.begin(), __unary_op());

for (auto it = vectorVar.begin(); it != vectorVar.end() ; it++) {
cout << "第一种方式:" << *it << endl;
}
cout << endl;

// 第三个参数接收返回值有啥用?没感受出来
// ==================================================================================

// TODO 第二种方式
vector<int> vectorVarResult; // vectorVarResult 大小空间
vectorVarResult.resize(vectorVar.size());
transform(vectorVar.begin(), vectorVar.end(), vectorVarResult.begin(), __unary_op());

for (auto it = vectorVarResult.begin(); it != vectorVarResult.end() ; it++) {
cout << "第二种方式:" << *it << endl;
}

return 0;
}

4.查找函数

4.1 find函数

find函数直接接受需要查找的内容,不接收仿函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main() {
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(), 10000);
vectorVar.insert(vectorVar.begin(), 20000);
vectorVar.insert(vectorVar.begin(), 30000);
vectorVar.insert(vectorVar.begin(), 40000);

// find 没有自定义仿函数
auto iteratorVar = find(vectorVar.begin(), vectorVar.end(), 40000);
if (iteratorVar != vectorVar.end()) {
cout << "查找到了" << endl;
} else {
cout << "没有找到" << endl;
}
return 0;

/*
...
find(_InputIterator __first, 开始位置 迭代器
_InputIterator __last, 结束位置 迭代器
const _Tp& __val) 需要查找的元素 40000
{
....
结论:对__find_if的封装而已
return std::__find_if(__first, __last,
__gnu_cxx::__ops::__iter_equals_val(__val));
}*/
}
4.2 find_if函数

find_if函数可以接收一个仿函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class __pred {
public:
int number;
__pred(int number) : number(number) {}
bool operator() (const int value) {
return number == value;
}
};

int main() {
vector<int> vectorVar;
vectorVar.insert(vectorVar.begin(), 10000);
vectorVar.insert(vectorVar.begin(), 20000);
vectorVar.insert(vectorVar.begin(), 30000);
vectorVar.insert(vectorVar.begin(), 40000);

auto it = find_if(vectorVar.begin(), vectorVar.end(), __pred(30000));

if (it != vectorVar.end()) {
cout << "查找到了" << endl;
} else {
cout << "没有找到" << endl;
}
return 0;

/* 知道怎么阅读算法包源码 1
...
find_if(_InputIterator __first, 开始位置 迭代器
_InputIterator __last, 结束位置 迭代器
_Predicate __pred) 自定义仿函数
{
... 监测工作而已
return std::__find_if(__first, __last,
__gnu_cxx::__ops::__pred_iter(__pred));
}

...
__find_if(_InputIterator __first, 开始位置 迭代器
_InputIterator __last, 结束位置 迭代器
_Predicate __pred, TODO 自定义仿函数
....)
{
while (__first != __last && !__pred(__first)) // __pred(__first) 自定义仿函数 怎么写 返回值bool 传入int类型
++__first; // 迭代器从开始位置挪动 算法思路: 指针++
return __first;
}
*/

}

5. 统计元素个数

5.1 count函数和count_if函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

// count 没有自定义仿函数
int main() {
vector<int> vectorVar;
vectorVar.push_back(1);
vectorVar.push_back(2);
vectorVar.push_back(3);
vectorVar.push_back(2);
vectorVar.push_back(4);
vectorVar.push_back(6);
vectorVar.push_back(8);
vectorVar.push_back(1);

int number = count(vectorVar.begin(), vectorVar.end(), 2);
cout << "等于2的个数是:" << number << endl;

// C++ 源码 函数适配器
number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(less<int>(), 2)); // 函数适配器 配合 less <
cout << "小于2的个数是:" << number << endl;

number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(greater<int>(), 2)); // 函数适配器 配合 less >
cout << "大于2的个数是:" << number << endl;

number = count_if(vectorVar.begin(), vectorVar.end(), bind2nd(equal_to<int>(), 2)); // 函数适配器 配合 less =
cout << "等于2的个数是:" << number << endl;

return 0;

// count_if 源码分析...
/**
....
count_if(_InputIterator __first, 迭代器 开始位置
_InputIterator __last, 迭代器 结束位置
_Predicate __pred) 自定义仿函数 __pred在源码里面可以知道 我们去写自定义仿函数的规则
{
.... 省略 监测工作而已
return std::__count_if(__first, __last,
__gnu_cxx::__ops::__pred_iter(__pred));
}

....
__count_if(_InputIterator __first,
_InputIterator __last,
_Predicate __pred)
{
typename iterator_traits<_InputIterator>::difference_type __n = 0; int __n
for (; __first != __last; ++__first) 思路:迭代器 ++ 挪动位置
if (__pred(__first)) 自定义仿函数 返回bool类型 ??? 迭代器类型
++__n;
return __n; // 最终 count_if 是返回int类型 __n ++后的 统计元素的个数
}
*/
}

6. 合并函数(merge)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

int main() {
vector<int> vectorVar1;
vectorVar1.push_back(10);
vectorVar1.push_back(20);
vectorVar1.push_back(30);
vectorVar1.push_back(40);

vector<int> vectorVar2;
vectorVar2.push_back(50);
vectorVar2.push_back(60);
vectorVar2.push_back(70);
vectorVar2.push_back(80);

// 合并成一个容器 result
vector<int> vectorResult;
vectorResult.resize(vectorVar1.size() + vectorVar2.size());

merge(vectorVar1.begin(), vectorVar1.end(), vectorVar2.begin(), vectorVar2.end(), vectorResult.begin());
for (auto itVar = vectorResult.begin(); itVar != vectorResult.end() ; itVar++) {
cout << *itVar <<endl;
}

return 0;

/**

...
merge(_InputIterator1 __first1, _InputIterator1 __last1, 第一个容器 位置
_InputIterator2 __first2, _InputIterator2 __last2, 第二个容器 位置
_OutputIterator __result) 最终合并后的结果
{
.... 监测工作而已
return _GLIBCXX_STD_A::__merge(__first1, __last1,
__first2, __last2, __result,
__gnu_cxx::__ops::__iter_less_iter());
}

template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
_GLIBCXX20_CONSTEXPR
_OutputIterator
__merge(_InputIterator1 __first1, _InputIterator1 __last1, 第一个容器 位置
_InputIterator2 __first2, _InputIterator2 __last2, 第二个容器 位置
_OutputIterator __result, 最终合并后的结果
_Compare __comp)
{
while (__first1 != __last1 && __first2 != __last2)
{

做 合并 算法处理工作
if (__comp(__first2, __first1))
{
*__result = *__first2;
++__first2;
}
else
{
*__result = *__first1;
++__first1;
}
++__result;
}

// 拷贝剩余数组1的值然后拷贝数组2的值
return std::copy(__first2, __last2,
std::copy(__first1, __last1, __result));
}

*/
}

7. 对容器进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

int main() {
vector<int> vectorVar;
vectorVar.push_back(10);
vectorVar.push_back(30);
vectorVar.push_back(20);

// if (__comp(__i, __first)) 自定义仿函数规则 返回值 bool 第一个参数int 第二个参数 是int 吗

// 内置 的 仿函数 less<int>()
// less<int>() 里面泛型==函数模版 没法确定好 第二个参数的类型【到底是什么类型?】

sort(vectorVar.begin(), vectorVar.end(), less<int>());
// sort(vectorVar.begin(), vectorVar.end(), greater<int>());

// 直接打印 vectorVar容器 此时 是不是就已经排序了
for (auto itVar = vectorVar.begin(); itVar != vectorVar.end() ; itVar++) {
cout << *itVar <<endl;
}
}

8. 对容器元素进行打乱

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

int main() {
vector<int> vectorVar; // vector默认是没有排序功能的,默认输出: 65 53 84
vectorVar.push_back(65);
vectorVar.push_back(53);
vectorVar.push_back(84);
vectorVar.push_back(11);
vectorVar.push_back(22);
vectorVar.push_back(33);
vectorVar.push_back(44);


sort(vectorVar.begin(), vectorVar.end(), less<int>()); // 排序后 53 65 82

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

// 直接打印 vectorVar容器 此时 是不是就已经排序了
for (auto itVar = vectorVar.begin(); itVar != vectorVar.end() ; itVar++) {
cout << *itVar << "\t";
// 84 65 53
}
return 0;
}

9. 复制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

int main() {
vector<int> vectorVar; // vector默认是没有排序功能的,默认输出: 65 53 84
vectorVar.push_back(100);
vectorVar.push_back(200);
vectorVar.push_back(300);
vectorVar.push_back(400);
vectorVar.push_back(500);
vectorVar.push_back(600);
vectorVar.push_back(700);

vector<int> vectorResult;
vectorResult.resize(vectorVar.size());

copy(vectorVar.begin(), vectorVar.end(), vectorResult.begin());
// 100 200 300 400 500 600 700

// 直接打印 vectorVar容器 此时 是不是就已经排序了
for (auto itVar = vectorResult.begin(); itVar != vectorResult.end() ; itVar++) {
cout << *itVar << "\t";
}

return 0;
}

10. 替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <vector> // stl包
#include <algorithm> // 算法包

using namespace std;

int age;

void set(int age) {
::age = age;
}

int main() {
vector<int> vectorVar; // vector默认是没有排序功能的,默认输出: 65 53 84
vectorVar.push_back(100);
vectorVar.push_back(200);
vectorVar.push_back(300);
vectorVar.push_back(400);
vectorVar.push_back(500);
vectorVar.push_back(600);

// 100 ~ 200 范围
// replace(vectorVar.begin(), vectorVar.begin() + 2, 200, 222);

// 所有范围
replace(vectorVar.begin(), vectorVar.end(), 300, 333);

// 直接打印 vectorVar容器 此时 是不是就已经排序了
for (auto itVar = vectorVar.begin(); itVar != vectorVar.end() ; itVar++) {
cout << *itVar << "\t";
}

return 0;
}