一、引言
※本文记录一些C++常用的算法,用于简单使用※
- 一般要使用C++的内置算法,需要包含以下三个头文件:
#include<algorithm>、#include<functional>、#include<numeric>
头文件 | 解释 |
#include<algorithm> | algorithm是STL头文件中最大的一个, 涉及:比较交换、查找、遍历、修改、复制等操作。 |
#include<functional> | 定义了一些函数模板,用于仿函数 |
#include<numeric> | 体积很小,仅仅包括几个在序列上进行简单数学运算的函数模板 |
二、常用遍历算法
2.1 for_each
for_each会遍历整个容器,它的使用方法如下所示:
声明 | 解释 |
for_each(iterator begin, iterator end, 仿函数或函数); | (使用前,记得包含头文 #include<algorithm>)
|
下面用一个小示例来具体说明如何使用for_each函数:
//函数
void printInt(int elem) {
cout << elem << " ";
}
//仿函数
class PrintInt {
public:
void operator()(int elem) const {
cout << elem << " ";
}
};
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
//第三个参数为仿函数
PrintInt print_int;
cout << "第三个参数是仿函数:" << endl;
for_each(v0.begin(), v0.end(), print_int);
cout << endl;
//第三个参数为函数
cout << "第三个参数是函数:" << endl;
for_each(v0.begin(), v0.end(), printInt);
cout << endl;
return 0;
}
程序的执行结果如下所示:
2.2 transform
transform会将一个容器的全部元素复制到另一个容器中,它的函数声明如下所示:
※注意※:在使用之前,一定要先让目标容器使用resize(源容器.size())先设置其容量!!。
声明 | 解释 |
transform(iterator begin1, iterator end1, iterator begin2, 仿函数或函数); | (使用前,记得包含头文 #include<algorithm>)
|
下面用一个小示例来具体说明如何使用transform函数:
//输出函数
void printInt(int elem) {
cout << elem << " ";
}
//函数:值+1
int changeInt(int elem) {
elem++;
return elem;
}
//仿函数:值-1
class ChangeInt {
public:
int operator()(int i) {
i--;
return i;
}
};
int main() {
vector<int> v0;//源容器
vector<int> v1;//目标容器:第四个参数使用函数
vector<int> v2;//目标容器:第四个参数使用仿函数
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
//输出v0
cout << "v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
//输出v1
cout << "v1 : [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
//输出v2
cout << "v2 : [";
for_each(v2.begin(), v2.end(), printInt);
cout << "]" << endl;
//使用transform函数:第四个参数使用函数
v1.resize(v0.size());
transform(v0.begin(), v0.end(), v1.begin(), changeInt);
//使用transform函数:第四个参数使用仿函数
v2.resize(v0.size());
ChangeInt change;
transform(v0.begin(), v0.end(), v2.begin(), change);
//输出v0
cout << "v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
//输出v1
cout << "v1 : [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
//输出v2
cout << "v2 : [";
for_each(v2.begin(), v2.end(), printInt);
cout << "]" << endl;
return 0;
}
以上例子,将第四个参数设置为函数,将v0的每个值+1后,搬运给v1;
将第四个参数设置为仿函数,将v0的每个值-1后,搬运给v2,程序执行结果如下:
三、常用查找算法
3.0 注意
针对自定义类型的查找算法:在比较过程中,其实程序并不知道如何比较两个元素是否相等,也就是没有对应的==运算符。因此,我们需要在自定义类中重载==运算符
(下文中只在find和find_if中做示例说明,此外的其余函数均同理)
※ binary_search只能用于有序序列!※
3.1 find
find用于查找容器中的指定元素。
如果找到,则返回元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:
声明 | 解释 |
find(iterator begin, iterator end, value); | (使用前,记得包含头文 #include<algorithm>)
|
3.1.1 内置类型元素的find
vector<int> v0;
for (int i = 0; i < 10; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4 5 6 7 8 9
vector<int>::iterator it4 = find(v0.begin(), v0.end(), 4);
cout << "find 4 : " << boolalpha << (*it4 == 4) << endl;
vector<int>::iterator it11 = find(v0.begin(), v0.end(), 11);
cout << "find 11 : " << boolalpha << (*it4 == 11) << endl;
程序的执行结果如下所示:
3.1.2 自定义类型元素的find
当我们需要查找的是自定义类型的元素时,在比较过程中,其实程序并不知道如何比较两个元素是否相等,也就是没有对应的==运算符。因此,我们需要在自定义类中重载==运算符:
//Person类
class Person {
public:
string name;
int age;
Person(string n, int a) : name(n), age(a){}
//重载==运算符
bool operator==(const Person &p) {
return (this->name == p.name) && (this->age == p.age);
}
};
//主函数
int main() {
vector<Person> vp;
Person p1("A", 18);
vp.push_back(p1);
Person p2("B", 18);
vp.push_back(p2);
Person p3("C", 18);
vp.push_back(p3);
Person p4("D", 18);
vp.push_back(p4);
Person p5("E", 18);
vp.push_back(p5);
//能找到的C
Person p_find("C", 18);
vector<Person>::iterator itp = find(vp.begin(), vp.end(), p_find);
if (itp == vp.end()) {
cout << "Not Find C!" << endl;
} else {
cout << "Find C !" << endl;
}
//找不到的W
Person p_nfind("W", 18);
itp = find(vp.begin(), vp.end(), p_nfind);
if (itp == vp.end()) {
cout << "Not Find W!" << endl;
}
else {
cout << "Find W !" << endl;
}
return 0;
}
程序的执行结果如下所示:
3.2 find_if
find_if用于查找容器中的指定条件的元素。
如果找到,则返回元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:
声明 | 解释 |
find_if(iterator begin, iterator end, _P); | (使用前,记得包含头文 #include<algorithm>)
(谓词就是返回值为bool的仿函数) |
3.2.1 内置类型元素的find
//函数 : 数字 > 1
bool greaterOne(const int &num) {
return (num > 1);
}
//仿函数: 数字 > 2
class GreaterTwo {
public:
bool operator()(const int& num) {
return (num > 2);
}
};
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}// v0 = 0 1 2 3 4
//第三个参数使用函数
vector<int>::iterator it1 = find_if(v0.begin(), v0.end(), greaterOne);
cout << "find greater than one num is (2): " << *it1 << endl;
//第三个参数使用谓词
GreaterTwo greaterTwo;
vector<int>::iterator it2 = find_if(v0.begin(), v0.end(), greaterTwo);
cout << "find greater than one num is (3): " << *it2 << endl;
return 0;
}
程序的执行结果如下所示:
3.2.2 内置类型元素的find_if
这里与find相似,也需要重载==运算符:
//Person类
class Person {
public:
string name;
int age;
Person(string n, int a) : name(n), age(a){}
//重载==运算符
bool operator==(const Person &p) {
return (this->name == p.name) && (this->age == p.age);
}
};
//函数 : 名字为A
bool isA(const Person &per) {
return (per.name == "A");
}
//仿函数: 名字为C
class IsC {
public:
bool operator()(const Person &per) {
return (per.name == "C");
}
};
//主函数
int main() {
vector<Person> vp;
Person p1("A", 10);
vp.push_back(p1);
Person p2("B", 20);
vp.push_back(p2);
Person p3("C", 30);
vp.push_back(p3);
Person p4("D", 40);
vp.push_back(p4);
Person p5("E", 50);
vp.push_back(p5);
//第三个参数为函数
vector<Person>::iterator ita = find_if(vp.begin(), vp.end(), isA);
cout << "find A's age is (10): " << ita->age << endl;
//第三个参数为谓词
IsC isC;
vector<Person>::iterator itc = find_if(vp.begin(), vp.end(), isC);
cout << "find C's age is (30): " << itc->age << endl;
程序运行的结果如下所示:
3.3 adjacent_find
adjacnet_find用于查找容器中的相邻重复的元素。
如果找到,则返回第一个元素的迭代器;如果没找到,则返回本容器的结束迭代器end()。声明如下:
声明 | 解释 |
adjacent_find(iterator begin, iterator end); | (使用前,记得包含头文 #include<algorithm>)
|
int main() {
vector<int> v0;
for (int i = 1; i < 4; i++) {
for (int j = 0; j < i; j++) {
v0.push_back(i);
}
}// v0 = 1 2 2 3 3 3
vector<int>::iterator it = adjacent_find(v0.begin(), v0.end());
cout << "*it (2): " << *it << endl;
return 0;
}
程序执行结果如下所示:
3.4 binary_search
※注意※:虽然查找速度快,在无序序列中不可以使用!!!!
binary_search用二分法查找容器中的指定条件的元素。
如果找到,则返回true;如果没找到,则返回false。声明如下:
声明 | 解释 |
binary_search(iterator begin, iterator end, value); | (使用前,记得包含头文 #include<algorithm>)
|
vector<int> v0;
for (int i = 0; i < 10; i++) {
v0.push_back(i);
}// v0 = 0 1 2 3 4 5 6 7 8 9
bool exist_4 = binary_search(v0.begin(), v0.end(), 4);
cout << "Is 4 exist : " << boolalpha << exist_4 << endl;
bool exist_10 = binary_search(v0.begin(), v0.end(), 10);
cout << "Is 10 exist : " << boolalpha << exist_10 << endl;
程序的执行结果如下所示:
3.5 count
count用于统计容器中指定元素的个数,并返回。声明如下:
声明 | 解释 |
count(iterator begin, iterator end, value); | (使用前,记得包含头文 #include<algorithm>)
|
vector<int> v0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < i; j++) {
v0.push_back(i);
}
}// v0 = 1 2 2 3 3 3 4 4 4 4
int count_3 = count(v0.begin(), v0.end(), 3);
cout << "3's count is (3): " << count_3 << endl;
int count_5 = count(v0.begin(), v0.end(), 5);
cout << "5's count is (0): " << count_5 << endl;
程序的执行结果如下所示:
3.6 count_if
count_if用于指定某种条件,然后统计容器中符合条件元素的个数,并返回。声明如下:
声明 | 解释 |
count(iterator begin, iterator end, _P); | (使用前,记得包含头文 #include<algorithm>)
|
//函数 > 3
bool greaterThree(const int& num) {
return (num > 3);
}
//仿函数 < 3
class LessThree {
public:
bool operator()(const int & num) {
return (num < 3);
}
};
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < i; j++) {
v0.push_back(i);
}
}// v0 = 1 2 2 3 3 3 4 4 4 4
int greater_3 = count_if(v0.begin(), v0.end(), greaterThree);//4 4 4 4
cout << "Num which greater than three is (4): " << greater_3 << endl;
LessThree lessThree;
int less_3 = count_if(v0.begin(), v0.end(), lessThree);//1 2 2
cout << "Num which less than three is (3): " << less_3 << endl;
return 0;
}
程序的执行结果如下所示:
四、常用排序算法
4.1 sort
sort用于对容器中的某段区间的元素进行排序(默认升序)。声明如下:
声明 | 解释 |
sort(iterator begin, iterator end, _P); | (使用前,记得包含头文 #include<algorithm>)
|
4.1.1 默认升序排序
sort默认排序为升序,示例如下:
//输出元素函数
void printInt(const int &num) {
cout << num << " ";
}
//主函数
int main() {
vector<int> v0;
v0.push_back(10);
v0.push_back(40);
v0.push_back(20);
v0.push_back(50);
v0.push_back(30);
//输出v0所有元素
cout << "Before sort, v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
sort(v0.begin(), v0.end());
//输出v0所有元素
cout << "After sort, v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
return 0;
}
程序执行结果如下所示:
4.1.2 指定排序规则(自定义类型)
当我们希望元素降序排序,当容器元素的类型是我们自定义类型,其实这两种情况是类似的,都需要告知sort我们的排序规则。这边是上文提及的第三个参数_P。
4.1.2.1 降序
我们可以使用内置仿函数greater<T>,来实现容器元素的降序排序,也可以通过自己写的
仿函数或函数告知规则。使用greater<T>时需包含头文件#include<functional>。示例如下:
//输出元素函数
void printInt(const int &num) {
cout << num << " ";
}
//函数:自定义降序规则
bool myIntDown(const int &num1, const int& num2) {
//排序规则其实就是:两个元素进行比较,把谁排在前边
//降序规则:如果num1 > num2,则 “把num排在前边” = true
return num1 > num2;
}
//仿函数:自定义降序规则
class MyDown {
public:
bool operator()(const int &num1, const int& num2) {
return num1 > num2;
}
};
//主函数
int main() {
vector<int> v0;//通过内置仿函数greater<T>
vector<int> v1;//通过自定义函数
vector<int> v2;//通过自定义仿函数
v0.push_back(10);
v0.push_back(40);
v0.push_back(20);
v0.push_back(50);
v0.push_back(30);
v1.push_back(10);
v1.push_back(40);
v1.push_back(20);
v1.push_back(50);
v1.push_back(30);
v2.push_back(10);
v2.push_back(40);
v2.push_back(20);
v2.push_back(50);
v2.push_back(30);
//输出v0、v1和v2的所有元素
cout << "Before sort, v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
cout << "Before sort, v1 : [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
cout << "Before sort, v2 : [";
for_each(v2.begin(), v2.end(), printInt);
cout << "]" << endl;
//降序排序
sort(v0.begin(), v0.end(), greater<int>());//通过内置仿函数greater<T>
sort(v1.begin(), v1.end(), myIntDown);//通过自定义函数
sort(v2.begin(), v2.end(), MyDown());//通过自定义仿函数
//输出v0、v1和v2的所有元素
cout << "After sort, v0 : [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
cout << "After sort, v1 : [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
cout << "After sort, v0 : [";
for_each(v2.begin(), v2.end(), printInt);
cout << "]" << endl;
return 0;
}
程序的执行结果如下所示:
4.1.2.2 自定义类型
与上边类似,自定义类型就是需要告知sort自己的排序规则。这里再解释一下排序规则:
无论是仿函数或函数,排序规则一般拥有两个参数:first和second,返回值为bool类型。
在容器中,first是second的前一个元素,而返回值就是代表当前顺序是否是对的。
用前边的降序来说明:当first > second,此时就是降序,所以应该return true;
当first < second,此时不是降序,所以应该return false;
下边再举一个小例子具体说明:
//自定义类型Thing
class Thing {
public :
//排序规则,先按照one升序,在按照two升序
int one;
int two;
Thing(int a, int b) : one(a), two(b) {}
};
//输出元素函数
void printThing(const Thing& thing) {
cout << "(" << thing.one << ", " << thing.two << ")" << endl;
}
//函数:自定义排序规则
bool sortThing(const Thing& first, const Thing& second) {
if (first.one < second.one) {
//如果first的one < second的one,这种顺序是对的
return true;
}
else if (first.one > second.one) {
//如果first的one > second的one,这种顺序是错误的
return false;
}
else {
//当one相等,则比较two
return first.two < second.two;
}
}
//仿函数:自定义排序规则
class SortT {
public:
bool operator()(const Thing& first, const Thing& second) {
if (first.one < second.one) {
//如果first的one < second的one,这种顺序是对的
return true;
}
else if (first.one > second.one) {
//如果first的one > second的one,这种顺序是错误的
return false;
}
else {
//当one相等,则比较two
return first.two < second.two;
}
}
};
//主函数
int main() {
vector<Thing> v0;
vector<Thing> v1;
Thing t0(0, 2);
v0.push_back(t0);
v1.push_back(t0);
Thing t1(1, 2);
v0.push_back(t1);
v1.push_back(t1);
Thing t2(0, 1);
v0.push_back(t2);
v1.push_back(t2);
Thing t3(2, 1);
v0.push_back(t3);
v1.push_back(t3);
Thing t4(1, 1);
v0.push_back(t4);
v1.push_back(t4);
Thing t5(3, 1);
v0.push_back(t5);
v1.push_back(t5);
//打印v0和v1的全部元素
cout << "Before sort :" << endl;
cout << "---v0---" << endl;
for_each(v0.begin(), v0.end(), printThing);
cout << "--------" << endl;
cout << "---v1---" << endl;
for_each(v1.begin(), v1.end(), printThing);
cout << "--------" << endl;
//sort
sort(v0.begin(), v0.end(), sortThing);//通过函数
sort(v1.begin(), v1.end(), SortT());//通过仿函数
//打印v0和v1的全部元素
cout << "After sort :" << endl;
cout << "---v0---" << endl;
for_each(v0.begin(), v0.end(), printThing);
cout << "--------" << endl;
cout << "---v1---" << endl;
for_each(v1.begin(), v1.end(), printThing);
cout << "--------" << endl;
return 0;
}
程序的执行结果如下所示:
4.2 random_shuffle
random_shuffle用于对容器中的某段区间的元素进行随机打乱排序。声明如下:
声明 | 解释 |
random_shuffle(iterator begin, iterator end); | (使用前,记得包含头文 #include<algorithm>)
|
//输出元素函数
void printInt(const int& num) {
cout << num << endl;
}
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
cout << "Before shuffle : " << endl;
for_each(v0.begin(), v0.end(), printInt);
random_shuffle(v0.begin(), v0.end());
cout << "After shuffle : " << endl;
for_each(v0.begin(), v0.end(), printInt);
return 0;
}
程序的执行结果如下所示:
4.3 merge
※注意※:使用merge之前,必须确保两个容器有序!!!
merge可以将两个容器的元素进行合并。声明如下:
声明 | 解释 |
merge(iterator begin1, iterator end1, iterator begin2, iterator end2, iterator target_iter); | (使用前,记得包含头文 #include<algorithm>)
(※注意※ 使用前请将目标容器resize) |
再次强调一次,在使用merge前需要满足以下两个条件:
条件1 | 被合并的两个容器元素必须有序 |
条件2 | 目标容器必须提前设置足够大的容量 |
//输出int元素
void printInt(const int &elem) {
cout << elem << " " << endl;
}
//主函数
int main() {
vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
vector<int> v2;
v2.push_back(4);
v2.push_back(5);
v2.push_back(6);
vector<int> v3;
v3.resize(v1.size() + v2.size());
merge(v1.begin(), v1.end() - 1, v2.begin(), v2.end() - 1, v3.begin());
for_each(v3.begin(), v3.end(), printInt);
return 0;
}
程序的执行结果如下所示:
4.4 reverse
reverse可以将容器中的指定区间的元素反转。声明如下:
声明 | 解释 |
reverse(iterator begin, iterator end); | (使用前,记得包含头文 #include<algorithm>)
|
//输出int元素
void printInt(const int &elem) {
cout << elem << " " << endl;
}
//主函数
int main() {
vector<int> v1;
for (int i = 0; i < 5; i++) {
v1.push_back(i);
}
cout << "Before reverse :" << endl;
for_each(v1.begin(), v1.end(), printInt);
reverse(v1.begin() + 1, v1.end() - 1);
cout << "After reverse :" << endl;
for_each(v1.begin(), v1.end(), printInt);
return 0;
}
程序的执行结果如下所示:
五、常用拷贝算法
(※注意※ 使用前请将目标容器resize)
copy用于将容器中指定区间的元素拷贝到另一个容器中,声明如下:
声明 | 解释 |
copy(iterator begin, iterator end, iterator des); | (使用前,记得包含头文 #include<algorithm>)
(※注意※ 使用前请将目标容器resize) |
//输出int元素
void printInt(const int &elem) {
cout << elem << " ";
}
//主函数
int main() {
vector<int> v0;
vector<int> v1;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}
cout << "Before copy v1 :[";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
v1.resize(v0.size());
copy(v0.begin(), v0.end(), v1.begin());
cout << "After copy v1 :[";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
return 0;
}
程序的结果如下所示:
六、常用替换算法
6.1 replace
replace用于将容器中指定区间的旧元素替换为新元素,声明如下:
声明 | 解释 |
replace(iterator begin, iterator end, Elem oldValue, Elem newValue); | (使用前,记得包含头文 #include<algorithm>)
|
//输出int元素
void printInt(const int &elem) {
cout << elem << " ";
}
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
v0.push_back(i);
v0.push_back(i);
}//v0 = 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
cout << "Before replace v0 :[";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
replace(v0.begin(), v0.end(), 2, 666);
//v0 = 0 0 0 1 1 1 666 666 666 3 3 3 4 4 4
cout << "After replace v0 :[";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
return 0;
}
程序的直接结果如下所示:
6.2 replace_if
replace_if用于将容器中指定区间的符合指定条件的元素替换为新元素,声明如下:
声明 | 解释 |
replace_if(iterator begin, iterator end, _P, Elem newValue); | (使用前,记得包含头文 #include<algorithm>)
|
//输出int元素
void printInt(const int &elem) {
cout << elem << " ";
}
//函数:指定条件 0 < num < 3
bool _P(const int& num) {
return (num > 0) && (num < 3);
}
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
v0.push_back(i);
v0.push_back(i);
}//v0 = 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4
cout << "Before replace v0 :[";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
replace_if(v0.begin(), v0.end(), _P, 666);
//v0 = 0 0 0 666 666 666 666 666 666 3 3 3 4 4 4
cout << "After replace v0 :[";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
return 0;
}
程序的执行结果如下所示:
6.3 swap
swap用于互换两个容器,声明如下:
声明 | 解释 |
swap(Container c1, Container c2); | (使用前,记得包含头文 #include<algorithm>)
|
//输出int元素
void printInt(const int &elem) {
cout << elem << " ";
}
//主函数
int main() {
vector<int> v1;
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}
cout << "Before swap:" << endl;
cout << "v0: [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
cout << "v1: [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
swap(v0, v1);
cout << "After swap:" << endl;
cout << "v0: [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
cout << "v1: [";
for_each(v1.begin(), v1.end(), printInt);
cout << "]" << endl;
return 0;
}
程序的执行结果如下所示:
七、常用的算术生成算法
(使用前,记得包含头文 #include<numeric>)
7.1 accumulate
accumulate用于统计容器中元素累计总和,声明如下:
声明 | 解释 |
accumulate(iterator begin, iterator end, initV); | (使用前,记得包含头文 #include<numeric>)
|
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
//15 + 0 + 1 + 2 + 3 + 4 = 25
int sum = accumulate(v0.begin(), v0.end(), 15);
cout << "sum : " << sum << endl;
return 0;
}
程序的执行结果如下所示:
7.2 fill
fill用于将容器的指定区间元素全部替换为新元素,声明如下:
声明 | 解释 |
fill(iterator begin, iterator end, newValue); | (使用前,记得包含头文 #include<numeric>)
|
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
cout << "Before fill :" << endl;
cout << "v0: [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
fill(v0.begin() + 1, v0.end() - 1, 666);
cout << "After fill :" << endl;
cout << "v0: [";
for_each(v0.begin(), v0.end(), printInt);
cout << "]" << endl;
return 0;
}
程序执行的结果如下所示:
八、集合间元素的交集、并集和差集算法
(※注意※ 使用前请确保两个容器为有序序列)
8.1 set_intersection
(※注意※ 使用前请确保两个容器为有序序列)
(※注意※ 使用前请将目标容器resize为二者容器的最小size)
set_intersection用于将两个集合容器的交集存储于目标容器,声明如下:
声明 | 解释 |
set_intersection(iterator begin1, iterator end2, iterator begin1, iterator end2, iterator target_begin); | (使用前,记得包含 #include<algorithum>)
(※注意※ 使用前请将目标容器resize) |
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
vector<int> v1;
for (int i = 2; i < 7; i++) {
v1.push_back(i);
}//v1 = 2 3 4 5 6
vector<int> vTarget;
vTarget.resize(min(v0.size(), v1.size()));//将vTarget进行resize
set_intersection(v0.begin(), v0.end(), v1.begin(), v1.end(), vTarget.begin());
for_each(vTarget.begin(), vTarget.end(), printInt);
return 0;
}
程序的执行结果如下所示:
8.2 set_union
(※注意※ 使用前请将目标容器resize为二者容器的size之和)
(※注意※ 使用前请确保两个容器为有序序列)
set_union用于将两个集合容器的并集存储于目标容器,声明如下:
声明 | 解释 |
set_union(iterator begin1, iterator end2, iterator begin1, iterator end2, iterator target_begin); | (使用前,记得包含 #include<algorithum>)
(※注意※ 使用前请将目标容器resize) |
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
vector<int> v1;
for (int i = 4; i < 10; i++) {
v1.push_back(i);
}//v1 = 4 5 6 7 8 9
vector<int> vTarget;
vTarget.resize(v0.size() + v1.size());//将vTarget进行resize
set_union(v0.begin(), v0.end(), v1.begin(), v1.end(), vTarget.begin());
for_each(vTarget.begin(), vTarget.end(), printInt);
return 0;
}
程序执行的结果如下所示:
(并集中,只存在一个4,因为set集合中不存在重复元素。
如果使用multiset的话,则并集中会存在两个4,因为multiset允许重复元素存在)
8.3 set_difference
(※注意※ 使用前请将目标容器resize为二者容器的size之和)
(※注意※ 使用前请确保两个容器为有序序列)
set_difference用于将第一个容器对于第二个容器的差集存储于目标容器,声明如下:
声明 | 解释 |
set_difference(iterator begin1, iterator end2, iterator begin1, iterator end2, iterator target_begin); | (使用前,记得包含 #include<algorithum>)
(※注意※ 使用前请将目标容器resize) |
//输出int元素
void printInt(const int &elem) {
cout << elem << " ";
}
//主函数
int main() {
vector<int> v0;
for (int i = 0; i < 5; i++) {
v0.push_back(i);
}//v0 = 0 1 2 3 4
vector<int> v1;
for (int i = 2; i < 7; i++) {
v1.push_back(i);
}//v1 = 2 3 4 5 6
vector<int> vTarget;
vTarget.resize(v0.size(), -1);//将vTarget进行resize
set_difference(v0.begin(), v0.end(), v1.begin(), v1.end(), vTarget.begin());
cout << "v0 对于 v1 的差集:" << endl;
for_each(vTarget.begin(), vTarget.end(), printInt);
cout << endl << "---------------------------" << endl;
vTarget.resize(v1.size(), - 1);//将vTarget进行resize
set_difference(v1.begin(), v1.end(), v0.begin(), v0.end(), vTarget.begin());
cout << "v1 对于 v0 的差集:" << endl;
for_each(vTarget.begin(), vTarget.end(), printInt);
cout << endl << "---------------------------" << endl;
return 0;
}
程序的执行结果如下所示: