C++笔记(39-42)end
STL三大组件:容器、算法、迭代器
三十九、算法-函数对象
#include<iostream>
using namespace std;
class Myprint {
public:
int num;
Myprint() :num(0) {};
void operator() (int n) {
cout << n << endl;
num++;
}
};
int main() {
Myprint my;
my(10); // 函数对象
my(10);
my(10);
my(10);
cout << my.num << endl;
Myprint you;
you(18);
you(18);
you(18);
cout << you.num << endl;
return 0;
/*output
10
10
10
10
4
18
18
18
3*/
}
四十、算法-谓语predicate
谓语Predicate:
如果一个函数对象(仿函数)中,重载的()的返回值类型是boo1类型,这样的函数对象(仿函数)其实就是谓语Predicate.
find_if(start,end,predicate):从给定的范围中,查询满足条件的元素。如果找到了,返回这个元素的迭代器;如果没有找到,就返回end.
#include<algorithm> :: sort
sort(start,end,predicate):使用指定的大小比较规则,对指定范围的元素进行排序.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Student {
private:
string _name;
int _age;
public:
Student(){}
Student(string name, int age) :_name(name), _age(age) {}
int age() {
return _age;
}
void desc() {
cout << "name: " << _name << " age: " << _age << endl;
}
};
// 一元谓语
class Yonger {
public:
bool operator() (Student& s) {
return s.age() < 1;
}
};
// 二元谓语
class Mycompare {
public:
bool operator() (Student& s1, Student& s2) {
return s1.age() < s2.age(); //从小到大排
}
};
void test01() {
vector<Student> v;
v.push_back(Student("1", 19));
v.push_back(Student("2", 17));
v.push_back(Student("3", 18));
v.push_back(Student("4", 20));
v.push_back(Student("5", 19));
v.push_back(Student("6", 11));
v.push_back(Student("7", 12));
v.push_back(Student("8", 14));
// 要求找到第一个age < 18 的Student
auto it = find_if(v.begin(), v.end(), Yonger());
if (it == v.end()) {
cout << "NO FIND" << endl;
}
else {
(*it).desc();
}
// 要求从小到大排序
sort(v.begin(), v.end(), Mycompare());
for (Student& s : v) {
s.desc();
}
}
int main() {
test01();
/*output
NO FIND
name : 6 age : 11
name : 7 age : 12
name : 8 age : 14
name : 2 age : 17
name : 3 age : 18
name : 1 age : 19
name : 5 age : 19
name : 4 age : 20
*/
return EXIT_SUCCESS;
}
四十一、内建函数对象
四十二、算法
1.遍历算法 for_each
for_each 遍历容器元素
@param beg 开始迭代器
@param end 结束迭代器
@param _callback 函数回调或者函数对象
@return 函数对象
for_each(iterator beg,iterator end,callbagk);
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
vector<int>* getVector() {
vector<int>* v = new vector<int>();
for (int i = 0; i < 10; i++) {
v->push_back(i);
}
return v;
}
class Myprint {
public:
void operator()(int i) {
cout << i <<" ";
}
};
void print(int i) {
cout << i << " ";
}
void test() {
// 获取到需要遍历的数据容器
vector<int>* v = getVector();
// 使用for_each算法进行遍历,使用到的是函数对象(仿函数)
for_each(v->begin(), v->end(), Myprint());
cout << endl;
// 使用for_each算法进行遍历,使用到的是普通函数引用
for_each(v->begin(), v->end(), print);
}
int main() {
test();
/*output
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/
return 0;
}
2.遍历算法 transform
transform算法 将指定容器区间元素搬运到另一容器中
注意 : transform 不会给目标容器分配内存,所以需要我们提前分配好内存
@param beg1 源容器开始迭代器
@param end1 源容器结束迭代器
@param beg2 目标容器开始迭代器
@param _callback 回调函数或者函数对象
@return 返回目标容器迭代器
transform(iterator beg1,iterator end1, iterator beg2, _callback);
3.查找算法 find
find算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置
find(iterator beg, iterator end, value): 将每一个元素与 value 进行 == 比较,故有必要重载 == 运算符
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
/*
find算法 查找元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value 查找的元素
@return 返回查找元素的位置
find(iterator beg, iterator end, value): 将每一个元素与 value 进行 == ,故有必要重载 == 运算符
*/
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i);
}
// 从这个容器中,查找5
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if (it == v.end()) {
cout << "没有找到指定的元素" << endl;
}
else {
cout << "找到了指定的元素:" << *it << endl;
}
}
class Student {
public:
string name;
int age;
Student() = default;
Student(string n, int a):name(n), age(a){}
bool operator== (const Student& s) {
return name == s.name && age == s.age;
}
};
void test02() {
vector<Student> v;
v.push_back(Student("1", 19));
v.push_back(Student("2", 17));
v.push_back(Student("3", 18));
v.push_back(Student("4", 20));
v.push_back(Student("5", 19));
v.push_back(Student("6", 11));
v.push_back(Student("7", 12));
v.push_back(Student("8", 14));
vector<Student>::iterator it = find(v.begin(), v.end(), Student("8", 190));
if (it == v.end()) {
cout << "没有找到指定的Student" << endl;
}
else {
cout << "找到了指定的Student:" << (*it).name << endl;
}
}
int main() {
//test01();
test02();
return EXIT_SUCCESS;
}
4.查找算法 find_if
find_if算法 条件查找
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param _callback 回调函数或者谓词(返回bo01类型的函数对象)
@return bool 查找返回true 否则false
find_if(iterator beg, iterator end, _callback):会将每一个元素带入到 callback 中来,不同于find 仅仅是使用 == 。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*
find_if算法 条件查找
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 回调函数或者谓词(返回bo01类型的函数对象)
@return bool 查找返回true 否则false
find_if(iterator beg, iterator end, _callback);
*/
class Student {
private:
string _name;
int _age;
public:
Student() {}
Student(string name, int age) :_name(name), _age(age) {}
int age() {
return _age;
}
void desc() {
cout << "name: " << _name << " age: " << _age << endl;
}
};
// 一元谓语
class Yonger {
public:
bool operator() (Student& s) {
return s.age() < 18;
}
};
void test01() {
vector<Student> v;
v.push_back(Student("1", 19));
v.push_back(Student("2", 17));
v.push_back(Student("3", 18));
v.push_back(Student("4", 20));
v.push_back(Student("5", 19));
v.push_back(Student("6", 11));
v.push_back(Student("7", 12));
v.push_back(Student("8", 14));
// 要求找到第一个age < 18 的Student
auto it = find_if(v.begin(), v.end(), Yonger());
if (it == v.end()) {
cout << "NO FIND" << endl;
}
else {
(*it).desc();
}
}
int main() {
test01();
return EXIT_SUCCESS;
}
5.查找算法 adjacent_find
adjacent_find算法 查找相邻重复元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 可不用,类似于find,有必要重写 ==
回调函数或者谓词(返回boo1类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器
adjacent find(iterator beg, iterator end, _callback);
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*
adjacent_find算法 查找相邻重复元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback 可不用,类似于find,有必要重写 ==
回调函数或者谓词(返回boo1类型的函数对象)
@return 返回相邻元素的第一个位置的迭代器
adjacent find(iterator beg, iterator end, _callback);
*/
void test01() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(2);
v.push_back(5);
v.push_back(5);
v.push_back(6);
v.push_back(1);
auto it = adjacent_find(v.begin(), v.end());
if (it == v.end()) {
cout << "没有找到" << endl;
}
else {
cout << "找到了:" << *it << endl;
}
}
class Student {
public:
string name;
int age;
Student() {}
Student(string name, int age) :name(name), age(age) {}
void desc() {
cout << "name: " << name << " age: " << age << endl;
}
/*bool operator== (const Student& s) {
return name == s.name && age == s.age;
}*/
};
struct callback01 {
bool operator() (const Student& s1, const Student& s2) {
return s1.age == s2.age && s1.name == s2.name;
}
};
void test02() {
vector<Student> v;
v.push_back(Student("1", 19));
v.push_back(Student("2", 17));
v.push_back(Student("3", 18));
v.push_back(Student("4", 20));
v.push_back(Student("4", 20));
v.push_back(Student("2", 17));
v.push_back(Student("5", 19));
v.push_back(Student("5", 19));
v.push_back(Student("6", 11));
v.push_back(Student("5", 19));
v.push_back(Student("7", 12));
v.push_back(Student("8", 14));
auto it = adjacent_find(v.begin(), v.end(), callback01());
if (it == v.end()) {
cout << "没有找到" << endl;
}
else {
cout << "找到了:" << it->name << endl;
}
}
int main() {
//test01();
test02();
return EXIT_SUCCESS;
}
6.查找算法 binary_search
存在重载,可使用callback
7.查找算法 count & count_if
count算法 统计元素出现次数
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value回调函数或者谓词(返回bool类型的函数对象)
@return int返回元素个数
count(iterator beg,iterator end,value);
注意:如果比较的是自定义的类型(类、结构体),此时需要配合==运算符重载,类似于 find
count_if算法 统计元素出现次数
@param beg 容器开始迭代器
Cparam end 容器结束迭代器
@param callback 回调函数或者谓词(返回boo1类型的函数对象)
@return int返回元素个数
count_if(iterator beg,iterator end,callback);
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct JishuPredicate {
bool operator()(int n) {
return n % 2 == 0;
}
};
int main() {
int arr[] = { 1,2,3,4,6,78,2,3,5,6,9,4,2,1,1,1,35,56,7 };
vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
//查找7出现了多少次
cout << count(v.begin(), v.end(),7) << endl;
//查找有多少个奇数
cout << count_if(v.begin(), v.end(), JishuPredicate()) << endl;
return 0;
}
8.排序算法 sort
sort算法 容器元素排序
@param beg 容器1开始迭代器
@param end 容器1结束迭代器
@param_callback 默认升序; 回调函数或者谓词(返回bool类型的函数对象)
sort(iterator beg,iterator end,_callback)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Student {
private:
string _name;
int _age;
public:
Student() {}
Student(string name, int age) :_name(name), _age(age) {}
int age() {
return _age;
}
void desc() {
cout << "name: " << _name << " age: " << _age << endl;
}
};
struct print {
void operator() (int i) {
cout << i << " ";
}
};
struct compare {
bool operator()( Student& s1, Student& s2) {
return s1.age() < s2.age();
}
};
void test02() {
int arr[] = { 1,2,3,4,6,78,2,3,5,6,9,4,2,1,1,1,35,56,7 };
vector<int> v(arr, arr + (sizeof(arr) / sizeof(int)));
for_each(v.begin(), v.end(), print());
cout << endl;
// 升序
sort(v.begin(), v.end());
for_each(v.begin(), v.end(), print());
cout << endl;
// 降序
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), print());
cout << endl;
}
void test01() {
vector<Student> v;
v.push_back(Student("1", 19));
v.push_back(Student("2", 17));
v.push_back(Student("3", 18));
v.push_back(Student("4", 20));
v.push_back(Student("5", 19));
v.push_back(Student("6", 11));
v.push_back(Student("7", 12));
v.push_back(Student("8", 14));
sort(v.begin(), v.end(), compare());
for (auto item : v) {
item.desc();
}
}
int main() {
test01();
//test02();
return EXIT_SUCCESS;
}
9.排序算法 merge
merge算法 容器元素合并,并存储到另一容器中
注意 : 两个容器必须是有序的
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest.begin())
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
/*
merge算法 容器元素合并,并存储到另一容器中
注意 : 两个容器必须是有序的
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
*/
void print(int i) {
cout << i << " ";
}
int main() {
int arr1[] = { 1,3,5,7,9 };
int arr2[] = { 0,2,4,6,8,10,12};
vector<int> v1(arr1, arr1 + (sizeof(arr1) / sizeof(int)));
vector<int> v2(arr2, arr2 + (sizeof(arr2) / sizeof(int)));
for_each(v1.begin(), v1.end(), print);
cout << endl;
for_each(v2.begin(), v2.end(), print);
cout << endl;
vector<int> v3;
v3.resize(v1.size() + v2.size());
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin());
for_each(v3.begin(), v3.end(), print);
cout << endl;
return 0;
}
10.排序算法 random_shuffle
random_shuffle算法 对指定范围内的元素随机调整次序
@param beg 容器开始迭代器
@param end 容器结束迭代器
random _shuffle(iterator beg,iterator end)
可以设置随机种子srand(int)
11.排序算法 reverse
reverse算法 反转指定范围的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
reverse(iterator beg, iterator end)
12.copy & replace & replace_if & swap
copy算法 将容器内指定范围的元素拷贝到另一容器中
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param dest 目标起始迭代器
copy(iterator beg,iterator end, iterator dest.begin())
replace算法 将容器内指定范围的旧元素修改为新元素
容器开始迭代器
@param beg
@param end 容器结束迭代器
@param oldvalue l元素
@param oldvalue 新元素
replace(iterator beg,iterator end,oldvalue,newvalue)
replace_if算法 将容器内指定范围满足条件的元素替换为新元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param callback函数回调或者谓词(返回B001类型的函数对象)
@param oldvalue 新元素
replace_if(iterator beg,iterator end,callback,newvalue)
swap算法 互换两个容器的元素
@param c1容器1
@param c2容器2
swap(container c1, container c2)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct Print {
void operator()(int i) {
cout << i << " ";
}
};
void test01() {
vector<int> v1;
v1.push_back(10);
v1.push_back(12);
v1.push_back(15);
v1.push_back(9);
v1.push_back(7);
vector<int> v2;
v2.resize(v1.size());
copy(v1.begin(), v1.end(), v2.begin());
for_each(v2.begin(), v2.end(), Print());
cout << endl;
}
void test02() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(1);
v.push_back(3);
v.push_back(1);
// 需求:将容器中的1都替换成100
replace(v.begin(),v.end(),1,100);
for_each(v.begin(), v.end(),Print());
cout << endl;
}
struct Filter {
bool operator()(int i) {
return i % 2 == 1;
}
};
void test03() {
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
v.push_back(6);
// 需求:将容器中的所有的奇数,替换成100
replace_if(v.begin(),v.end(),Filter(),100);
for_each(v.begin(), v.end(),Print());
}
void test04() {
int arr1[] = { 1,3,5,7,9 };
int arr2[] = { 2,4,6,8,0,121,4,16 };
vector<int> v1(arr1, arr1 + (sizeof(arr1) / sizeof(int)));
vector<int> v2(arr2, arr2 + (sizeof(arr2) / sizeof(int)));
swap(v1, v2);
for_each(v1.begin(), v1.end(), Print());
cout << endl;
for_each(v2.begin(),v2.end(), Print());
}
int main() {
//test01();
//test02();
//test03();
test04();
return 0;
}
13.accumulate & fill
accumulate算法 计算容器元素累计总和+value
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value累加值
include numeric :: accumulate(iterator beg,iterator end,value)
fill算法 向容器中添加元素,覆盖之前的元素
@param beg 容器开始迭代器
@param end 容器结束迭代器
@param value t填充元系
fill(iterator beg,iterator end, value)
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
using namespace std;
struct print {
void operator() (int i){
cout << i << " ";
}
};
int main() {
vector<int> v(5, 10);
// 10 10 10 10 10 100 相加 = 150
cout << accumulate(v.begin(), v.end(), 100) << endl;
// 前 2 个元素替换为 9
fill(v.begin(), v.begin()+2, 9);
for_each(v.begin(), v.end(), print());
/*
output
150
9 9 10 10 10
*/
return 0;
}
14.集合算法 set_intersection union difference
set_intersection算法 求两个set集合的交集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
set_union算法 求两个set集合的并集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest 目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
set _union(iterator begl, iterator end1, iterator beg2, iterator end2, iterator dest)
set_difference算法 求两个set集合的差集
注意:两个集合必须是有序序列
@param beg1 容器1开始迭代器
@param end1 容器1结束迭代器
@param beg2 容器2开始迭代器
@param end2 容器2结束迭代器
@param dest目标容器开始迭代器
@return 目标容器的最后一个元素的迭代器地址
set difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest)
v1在前,v2在后,求:v1有的, v2没有
v2在前,v1在后,求:v2有的, v1没有
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main() {
int arr1[] = {1,2,4,65,7,8,8,9,6,46,7,89,0};
int arr2[] = {1,3,5,6,2,7,8,9,56,3,3,4,4,5,6,8};
vector<int> v1(arr1, arr1 + (sizeof(arr1) / sizeof(int)));
vector<int> v2(arr2, arr2 + (sizeof(arr2) / sizeof(int)));
sort(v1.begin(), v1.end());
sort(v2.begin(), v2.end());
for (const int& ele : v1) {
cout << ele << " ";
}
cout << endl;
for (const int& ele : v2) {
cout << ele << " ";
}
cout << endl;
// 求交集
vector<int> res1;
res1.resize(min(v1.size(),v2.size()));
//返回的是交集中最后一个元素的下一位的迭代器
vector<int>::iterator it1 = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), res1.begin());
for (vector<int>::iterator it = res1.begin(); it != it1; it++) {
cout << *(it) << " ";
}
cout << endl;
// 求并集
vector<int> res2;
res2.resize(v1.size() + v2.size());
vector<int>::iterator it2 = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), res2.begin());
for (vector<int>::iterator it = res2.begin(); it != it2; it++) {
cout << *(it) << " ";
}
cout << endl;
// 求差集
vector<int>res3;
res3.resize(max(v1.size(),v2.size()));
// v1在前,v2在后,求:v1有的, v2没有
vector<int>::iterator it3 = set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), res3.begin());
for (vector<int>::iterator it = res3.begin(); it != it3; it++) {
cout << *(it) << " ";
}
cout << endl;
// v2在前,v1在后,求:v2有的, v1没有
vector<int>::iterator it4 = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), res3.begin());
for (vector<int>::iterator it = res3.begin(); it != it4; it++) {
cout << *(it) << " ";
}
cout << endl;
/*
output
0 1 2 4 6 7 7 8 8 9 46 65 89
1 2 3 3 3 4 4 5 5 6 6 7 8 8 9 56
1 2 4 6 7 8 8 9
0 1 2 3 3 3 4 4 5 5 6 6 7 7 8 8 9 46 56 65 89
0 7 46 65 89
3 3 3 4 5 5 6 56
*/
return 0;
}