Wiki
Common Algorithms
Existing English translations were reused. 14 current source blocks remain in Simplified Chinese, without triggering paid translation.
1.STL- Common Algorithms
Overview:
-
The algorithm is mainly composed of the header files
<algorithm><functional><numeric>composition. -
<algorithm>It is the largest of all STL header files, covering comparison, swapping, searching, traversal operations, copying, modification, and so on. -
<numeric>It is very small and includes only a few template functions that perform simple mathematical operations on sequences. -
<functional>It defines some template classes used to declare function objects.
1.1.常用范围限制算法
1.1.1.std::clamp(C++17)
Function description:
- 把一个值限制在闭区间
[下限, 上限]内,也叫“限幅”或“钳位”。 - 小于下限时返回下限,大于上限时返回上限,在区间内时返回原值。
- 属于标准库的 STL 算法,定义在
<algorithm>中,C++17 起支持。
Function prototype:
template<class T>
constexpr const T& clamp(const T& v, const T& lo, const T& hi);
日常使用时写成 std::clamp(值, 下限, 上限) 即可。它返回限制后的结果,不会直接修改传入的变量;要更新原变量,需要接收返回值。
| 调用 | 返回值 | 原因 |
|---|---|---|
std::clamp(-5, 0, 10) |
0 |
小于下限 |
std::clamp(0, 0, 10) |
0 |
等于下限 |
std::clamp(6, 0, 10) |
6 |
位于区间内 |
std::clamp(10, 0, 10) |
10 |
等于上限 |
std::clamp(15, 0, 10) |
10 |
大于上限 |
Example:
下面先观察不同输入的返回值,再把速度指令限制在 [-2.0, 2.0] 内。
#include <algorithm>
#include <initializer_list>
#include <iostream>
int main()
{
for (int value : {-5, 0, 6, 10, 15})
{
int limited = std::clamp(value, 0, 10);
std::cout << value << " -> " << limited << '\n';
}
double speed = 3.5;
double limitedSpeed = std::clamp(speed, -2.0, 2.0);
std::cout << "original speed: " << speed << '\n';
std::cout << "limited speed: " << limitedSpeed << '\n';
// 需要修改原变量时,把结果赋值回去。
speed = std::clamp(speed, -2.0, 2.0);
std::cout << "updated speed: " << speed << '\n';
return 0;
}
Operation result:
-5 -> 0
0 -> 0
6 -> 6
10 -> 10
15 -> 10
original speed: 3.5
limited speed: 2
updated speed: 2
使用 GCC 或 Clang 时,编译示例需要启用 C++17 或更高标准,例如 g++ -std=c++17 main.cpp -o main。
常见错误:
- 上下限写反:默认比较方式要求
lo <= hi。例如std::clamp(5, 10, 0)不会自动交换上下限,这样写会产生未定义行为。 - 参数类型不一致:直接调用时,三个参数应使用相同类型。例如
double speed = 3.5;应写std::clamp(speed, -2.0, 2.0),写成std::clamp(speed, -2, 2)会导致模板类型推导失败。 - 用引用接收临时量:返回类型是
const T&,结果可能引用输入值或某个边界。如果边界是临时量,例如const auto& result = std::clamp(15, 0, 10);,语句结束后引用会悬空。日常保存数值结果时,使用auto result = std::clamp(15, 0, 10);按值接收即可。 - 把它当作非法输入检查:限幅会直接把越界值变成边界值。如果业务要求拒绝非法输入,应先判断范围;浮点数还应按业务需要检查
NaN,不能指望clamp自动处理。
总结:std::clamp 适合速度、音量、亮度等有明确上下限的数值。它既属于 STL 算法,也属于 C++17 引入的现代 C++ 标准库工具。
1.2.Common traversal algorithms
Learning Objectives:
- Master commonly used traversal algorithms
Algorithm Introduction:
for_each//Traverse the containertransform//Move the container to another container
1.2.1.for_each
Function description:
- Implement container traversal
Function prototype:
-
for_each(iterator beg, iterator end, _func);// Traversal algorithm: traverse container elements
// beg start iterator
// end end iterator
// _func function or function object
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//普通函数
void print01(int val)
{
cout << val << " ";
}
//函数对象
class print02
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
//for_each算法基本用法
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//遍历算法
for_each(v.begin(), v.end(), print01);
cout << endl;
for_each(v.begin(), v.end(), print02());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
**Summary:** for_each is the most commonly used traversal algorithm in practical development and must be mastered proficiently.
1.2.2.transform
Function description:
- Move the container into another container
Function prototype:
transform(iterator beg1, iterator end1, iterator beg2, _func);
//beg1 Source container begin iterator
//end1 Source container end iterator
//beg2 Iterator to the beginning of the target container
//_func Function or function object
Example:
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
//常用遍历算法 搬运 transform
class TransForm
{
public:
int operator()(int val)
{
return val;
}
};
class MyPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
vector<int>vTarget; //目标容器
vTarget.resize(v.size()); // 目标容器需要提前开辟空间
transform(v.begin(), v.end(), vTarget.begin(), TransForm());
for_each(vTarget.begin(), vTarget.end(), MyPrint());
}
int main() {
test01();
return 0;
}
Operation result:
0 1 2 3 4 5 6 7 8 9
Summary: The target container for handling must have space allocated in advance; otherwise, handling cannot proceed normally.
1.3.Common Search Algorithms
Learning objectives:
- Master commonly used search algorithms
Algorithm Introduction:
find//Find elementfind_if//Find element by conditionadjacent_find//Find adjacent duplicate elementsbinary_search//Binary search methodcount//Count the number of elementscount_if//Count the number of elements by condition
1.3.1.find
Function description:
- Find the specified element; if found, return an iterator to the specified element; if not found, return the end iterator end().
Function prototype:
-
find(iterator beg, iterator end, value);// Find an element by value; if found, return an iterator to the specified position; if not found, return the end iterator position
// beg is the starting iterator
// end is the ending iterator
// value is the element to find
Example:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i + 1);
}
//查找容器中是否有 5 这个元素
vector<int>::iterator it = find(v.begin(), v.end(), 5);
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到:" << *it << endl;
}
}
class Person {
public:
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;
}
return false;
}
public:
string m_Name;
int m_Age;
};
void test02() {
vector<Person> v;
//创建数据
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<Person>::iterator it = find(v.begin(), v.end(), p2);
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
}
}
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
Summary: Use find to locate a specified element in a container; the return value is aniterator
1.3.2.find_if
Function description:
- Find elements by condition
Function prototype:
-
find_if(iterator beg, iterator end, _Pred);// Find element by value; if found, return an iterator to the specified position; if not found, return the end iterator
// beg: begin iterator
// end: end iterator
// _Pred: function or predicate (a functor that returns bool)
Example:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
//内置数据类型
class GreaterFive
{
public:
bool operator()(int val)
{
return val > 5;
}
};
void test01() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i + 1);
}
vector<int>::iterator it = find_if(v.begin(), v.end(), GreaterFive());
if (it == v.end()) {
cout << "没有找到!" << endl;
}
else {
cout << "找到大于5的数字:" << *it << endl;
}
}
//自定义数据类型
class Person {
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
public:
string m_Name;
int m_Age;
};
class Greater20
{
public:
bool operator()(Person &p)
{
return p.m_Age > 20;
}
};
void test02() {
vector<Person> v;
//创建数据
Person p1("aaa", 10);
Person p2("bbb", 20);
Person p3("ccc", 30);
Person p4("ddd", 40);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
vector<Person>::iterator it = find_if(v.begin(), v.end(), Greater20());
if (it == v.end())
{
cout << "没有找到!" << endl;
}
else
{
cout << "找到姓名:" << it->m_Name << " 年龄: " << it->m_Age << endl;
}
}
int main() {
//test01();
test02();
return 0;
}
Operation result:
找到姓名:ccc 年龄: 30
Summary: find_if Conditional lookup makes searching more flexible, and the provided functors can change different strategies
1.3.3.adjacent_find
Function description:
- Find adjacent duplicate elements
Function prototype:
-
adjacent_find(iterator beg, iterator end);// Find adjacent duplicate elements, returns an iterator to the first position of the adjacent elements
// beg Start iterator
// end End iterator
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(5);
v.push_back(2);
v.push_back(4);
v.push_back(4);
v.push_back(3);
//查找相邻重复元素
vector<int>::iterator it = adjacent_find(v.begin(), v.end());
if (it == v.end()) {
cout << "找不到!" << endl;
}
else {
cout << "找到相邻重复元素为:" << *it << endl;
}
}
Run result: This code block does not contain the main function; it is a syntax, interface, or multi-file example and cannot be run independently, so there is no terminal output.
Summary: If a problem in an interview asks you to find adjacent duplicate elements, remember to use the adjacent_find algorithm in the STL.
1.3.4.binary_search
Function description:
- Check whether the specified element exists
Function prototype:
-
bool binary_search(iterator beg, iterator end, value);// Find the specified element, return true if found, otherwise false
// Note: Not available inunordered sequences
// beg Start iterator
// end End iterator
// value The element to find
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void test01()
{
vector<int>v;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//二分查找
bool ret = binary_search(v.begin(), v.end(),2);
if (ret)
{
cout << "找到了" << endl;
}
else
{
cout << "未找到" << endl;
}
}
int main() {
test01();
return 0;
}
Operation result:
找到了
**Summary:** The binary search method has very high search efficiency; it is worth noting that the elements in the container being searched must be in an ordered sequence.
1.3.5.count
Function description:
- Count the number of elements
Function prototype:
-
count(iterator beg, iterator end, value);// Count the number of occurrences of an element
// beg Start iterator
// end End iterator
// value The element to count
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//内置数据类型
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(5);
v.push_back(3);
v.push_back(4);
v.push_back(4);
int num = count(v.begin(), v.end(), 4);
cout << "4的个数为: " << num << endl;
}
//自定义数据类型
class Person
{
public:
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;
}
}
string m_Name;
int m_Age;
};
void test02()
{
vector<Person> v;
Person p1("刘备", 35);
Person p2("关羽", 35);
Person p3("张飞", 35);
Person p4("赵云", 30);
Person p5("曹操", 25);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
Person p("诸葛亮",35);
int num = count(v.begin(), v.end(), p);
cout << "num = " << num << endl;
}
int main() {
//test01();
test02();
return 0;
}
Operation result:
num = 3
Summary: When counting custom data types, it is necessary to overload operator==
1.3.6.count_if
Function description:
- Count elements by condition
Function prototype:
-
count_if(iterator beg, iterator end, _Pred);// Count the number of occurrences of elements by condition
// beg Start iterator
// end End iterator
// _Pred Predicate
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class Greater4
{
public:
bool operator()(int val)
{
return val >= 4;
}
};
//内置数据类型
void test01()
{
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(4);
v.push_back(5);
v.push_back(3);
v.push_back(4);
v.push_back(4);
int num = count_if(v.begin(), v.end(), Greater4());
cout << "大于4的个数为: " << num << endl;
}
//自定义数据类型
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
class AgeLess35
{
public:
bool operator()(const Person &p)
{
return p.m_Age < 35;
}
};
void test02()
{
vector<Person> v;
Person p1("刘备", 35);
Person p2("关羽", 35);
Person p3("张飞", 35);
Person p4("赵云", 30);
Person p5("曹操", 25);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
v.push_back(p4);
v.push_back(p5);
int num = count_if(v.begin(), v.end(), AgeLess35());
cout << "小于35岁的个数:" << num << endl;
}
int main() {
//test01();
test02();
return 0;
}
Operation result:
小于35岁的个数:2
**Summary:** Use count for statistics by value, and use count_if for statistics by condition.
1.4.Common Sorting Algorithms
Learning Objectives:
- Master commonly used sorting algorithms
Algorithm Introduction:
sort//Sort elements within the containerrandom_shuffle//Shuffle randomly reorder elements within the specified rangemerge// Merge container elements and store them into another containerreverse// Reverse the elements in the specified range
1.4.1.sort
Function description:
- Sort the elements within the container
Function prototype:
-
sort(iterator beg, iterator end, _Pred);// Find an element by value; if found, return an iterator to the specified position; if not found, return the end iterator
// beg start iterator
// end end iterator
// _Pred predicate
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
void myPrint(int val)
{
cout << val << " ";
}
void test01() {
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
//sort默认从小到大排序
sort(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint);
cout << endl;
//从大到小排序
sort(v.begin(), v.end(), greater<int>());
for_each(v.begin(), v.end(), myPrint);
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
10 20 30 40 50
50 40 30 20 10
**Summary:** Sorting is one of the most commonly used algorithms in development and must be mastered proficiently.
1.4.2.random_shuffle
Function description:
- Shuffle Randomly reorder elements within a specified range
Function prototype:
-
random_shuffle(iterator beg, iterator end);// Randomly adjust the order of elements within the specified range
// beg Start iterator
// end End iterator
Example:
#include <iostream>
#include <algorithm>
#include <vector>
#include <ctime>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
srand((unsigned int)time(NULL));
vector<int> v;
for(int i = 0 ; i < 10;i++)
{
v.push_back(i);
}
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//打乱顺序
random_shuffle(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Run results (random numbers may vary with the runtime environment; the following is an example from one run):
0 1 2 3 4 5 6 7 8 9
2 4 5 8 6 0 9 3 7 1
**Summary:**random_shuffle The shuffle algorithm is quite practical; remember to add a random seed when using it.
1.4.3.merge
Function description:
- Merge two container elements and store them in another container.
Function prototype:
-
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);// Merge container elements and store them in another container
// Note: The two containers must beordered
// beg1 Iterator to the beginning of container 1 // end1 Iterator to the end of container 1 // beg2 Iterator to the beginning of container 2 // end2 Iterator to the end of container 2 // dest Iterator to the beginning of the destination container
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10 ; i++)
{
v1.push_back(i);
v2.push_back(i + 1);
}
vector<int> vtarget;
//目标容器需要提前开辟空间
vtarget.resize(v1.size() + v2.size());
//合并 需要两个有序序列
merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin());
for_each(vtarget.begin(), vtarget.end(), myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10
**Summary:** The two containers merged by merge must be ordered sequences.
1.4.4.reverse
Function description:
- Reverse the elements in the container
Function prototype:
-
reverse(iterator beg, iterator end);// Reverses the elements in the specified range
// beg The beginning iterator
// end The ending iterator
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.push_back(10);
v.push_back(30);
v.push_back(50);
v.push_back(20);
v.push_back(40);
cout << "反转前: " << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
cout << "反转后: " << endl;
reverse(v.begin(), v.end());
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
// 程序从 main 函数开始执行,下面的语句会按顺序运行。
test01();
// 返回 0 表示程序正常结束。
return 0;
}
Operation result:
反转前:
10 30 50 20 40
反转后:
40 20 50 30 10
**Summary:** `reverse` reverses the elements within the interval; this may be covered in interview questions.
1.5.Common copy and replace algorithms
Learning Objectives:
- Master commonly used copy and replace algorithms
Algorithm Introduction:
copy// Copy the elements in the specified range within the container to another containerreplace// Modify the old elements in the specified range within the container to new elementsreplace_if// Replace the elements that meet the condition in the specified range within the container with new elementsswap// Swap the elements of two containers
1.5.1.copy
Function description:
- Copy the elements in the specified range from one container to another container.
Function prototype:
-
copy(iterator beg, iterator end, iterator dest);// Find an element by value; if found, return an iterator to the specified position; if not found, return the end iterator position
// beg Start iterator
// end End iterator
// dest Target start iterator
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
for (int i = 0; i < 10; i++) {
v1.push_back(i + 1);
}
vector<int> v2;
v2.resize(v1.size());
copy(v1.begin(), v1.end(), v2.begin());
for_each(v2.begin(), v2.end(), myPrint());
cout << endl;
}
int main() {
// 程序从 main 函数开始执行,下面的语句会按顺序运行。
test01();
// 返回 0 表示程序正常结束。
return 0;
}
Operation result:
1 2 3 4 5 6 7 8 9 10
**Summary:** When using the copy algorithm for copying, remember to allocate space for the target container in advance
1.5.2.replace
Function description:
- Modify the old elements within the specified range in the container to new elements
Function prototype:
-
replace(iterator beg, iterator end, oldvalue, newvalue);// Replace old elements in the range with new elements
// beg Start iterator
// end End iterator
// oldvalue Old element
// newvalue New element
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.push_back(20);
v.push_back(30);
v.push_back(20);
v.push_back(40);
v.push_back(50);
v.push_back(10);
v.push_back(20);
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//将容器中的20 替换成 2000
cout << "替换后:" << endl;
replace(v.begin(), v.end(), 20,2000);
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
替换前:
20 30 20 40 50 10 20
替换后:
2000 30 2000 40 50 10 2000
**Summary:** replace replaces elements within the interval that satisfy the condition
1.5.3.replace_if
Function description:
- Replace the elements in the range that satisfy the condition with the specified element.
Function prototype:
-
replace_if(iterator beg, iterator end, _pred, newvalue);// Replace elements conditionally, elements that satisfy the condition are replaced with the specified element
// beg Start iterator
// end End iterator
// _pred Predicate
// newvalue New element to replace with
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
class ReplaceGreater30
{
public:
bool operator()(int val)
{
return val >= 30;
}
};
void test01()
{
vector<int> v;
v.push_back(20);
v.push_back(30);
v.push_back(20);
v.push_back(40);
v.push_back(50);
v.push_back(10);
v.push_back(20);
cout << "替换前:" << endl;
for_each(v.begin(), v.end(), myPrint());
cout << endl;
//将容器中大于等于的30 替换成 3000
cout << "替换后:" << endl;
replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000);
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
替换前:
20 30 20 40 50 10 20
替换后:
20 3000 20 3000 3000 10 20
**总结:**replace_if按条件查找,可以利用仿函数灵活筛选满足的条件
1.5.4.swap
Function description:
- Swap the elements of two containers
Function prototype:
-
swap(container c1, container c2);// Swap the elements of two containers
// c1 container 1
// c2 container 2
Example:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10; i++) {
v1.push_back(i);
v2.push_back(i+100);
}
cout << "交换前: " << endl;
for_each(v1.begin(), v1.end(), myPrint());
cout << endl;
for_each(v2.begin(), v2.end(), myPrint());
cout << endl;
cout << "交换后: " << endl;
swap(v1, v2);
for_each(v1.begin(), v1.end(), myPrint());
cout << endl;
for_each(v2.begin(), v2.end(), myPrint());
cout << endl;
}
int main() {
// 程序从 main 函数开始执行,下面的语句会按顺序运行。
test01();
// 返回 0 表示程序正常结束。
return 0;
}
Operation result:
交换前:
0 1 2 3 4 5 6 7 8 9
100 101 102 103 104 105 106 107 108 109
交换后:
100 101 102 103 104 105 106 107 108 109
0 1 2 3 4 5 6 7 8 9
**Summary:** When swapping containers, ensure that the containers being swapped are of the same type.
1.6.Common arithmetic generation algorithms
Learning Objectives:
- Master commonly used arithmetic generation algorithms
Note:
- Arithmetic generation algorithms belong to small algorithms; the header file to include when using them is
#include <numeric>
Algorithm Introduction:
-
accumulate// Compute the cumulative sum of container elements -
fill// Add elements to the container
1.6.1.accumulate
Function description:
- Calculate the cumulative sum of container elements within the range
Function prototype:
-
accumulate(iterator beg, iterator end, value);// Calculate the cumulative sum of container elements
// beg Start iterator
// end End iterator
// value Initial value
Example:
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;
void test01()
{
vector<int> v;
for (int i = 0; i <= 100; i++) {
v.push_back(i);
}
int total = accumulate(v.begin(), v.end(), 0);
cout << "total = " << total << endl;
}
int main() {
// 程序从 main 函数开始执行,下面的语句会按顺序运行。
test01();
// 返回 0 表示程序正常结束。
return 0;
}
Operation result:
total = 5050
**Summary:** When using accumulate, note that the header file is numeric. This algorithm is very practical.
1.6.2.fill
Function description:
- Fill the container with the specified elements
Function prototype:
-
fill(iterator beg, iterator end, value);// Fill elements into the container
// beg Begin iterator
// end End iterator
// value Value to fill
Example:
#include <iostream>
#include <numeric>
#include <vector>
#include <algorithm>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
vector<int> v;
v.resize(10);
//填充
fill(v.begin(), v.end(), 100);
for_each(v.begin(), v.end(), myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
100 100 100 100 100 100 100 100 100 100
**Summary:** fill can be used to fill the elements within a container range with a specified value.
1.7.Common collection algorithms
Learning Objectives:
- Master commonly used collection algorithms
Algorithm Introduction:
-
set_intersection// Find the intersection of two containers -
set_union// Find the union of two containers -
set_difference// Find the difference of two containers
1.7.1.set_intersection
Function description:
- Find the intersection of two containers
Function prototype:
-
set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);// Find the intersection of two sets
// Note: Both sets must be ordered sequences
// beg1 Iterator to the beginning of container 1 // end1 Iterator to the end of container 1 // beg2 Iterator to the beginning of container 2 // end2 Iterator to the end of container 2 // dest Iterator to the beginning of the destination container
Example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
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 itEnd =
set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
5 6 7 8 9
Summary:
- The two sets whose intersection is to be computed must be ordered sequences
- The space to be allocated for the target container needs to be taken fromthe smaller value of the two containers
- set_intersection The return value is also the position of the last element in the intersection
1.7.2.set_union
Function description:
- Find the union of two sets
Function prototype:
-
set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);// Compute the union of two sets
// Note: Both sets must be ordered sequences
// beg1 Iterator to the beginning of container 1 // end1 Iterator to the end of container 1 // beg2 Iterator to the beginning of container 2 // end2 Iterator to the end of container 2 // dest Iterator to the beginning of the destination container
Example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
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(v1.size() + v2.size());
//返回目标容器的最后一个元素的迭代器地址
vector<int>::iterator itEnd =
set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Summary:
- 求并集的两个集合必须的有序序列
- 目标容器开辟空间需要两个容器相加
- set_union返回值既是并集中最后一个元素的位置
1.7.3.set_difference
Function description:
- Find the difference of two sets
Function prototype:
-
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);// Compute the difference of two sets
// Note: Both sets must be ordered sequences
// beg1 Iterator to the beginning of container 1 // end1 Iterator to the end of container 1 // beg2 Iterator to the beginning of container 2 // end2 Iterator to the end of container 2 // dest Iterator to the beginning of the destination container
Example:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class myPrint
{
public:
void operator()(int val)
{
cout << val << " ";
}
};
void test01()
{
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( max(v1.size() , v2.size()));
//返回目标容器的最后一个元素的迭代器地址
cout << "v1与v2的差集为: " << endl;
vector<int>::iterator itEnd =
set_difference(v1.begin(), v1.end(), v2.begin(), v2.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
cout << "v2与v1的差集为: " << endl;
itEnd = set_difference(v2.begin(), v2.end(), v1.begin(), v1.end(), vTarget.begin());
for_each(vTarget.begin(), itEnd, myPrint());
cout << endl;
}
int main() {
test01();
return 0;
}
Operation result:
v1与v2的差集为:
0 1 2 3 4
v2与v1的差集为:
10 11 12 13 14
Summary:
- 求差集的两个集合必须的有序序列
- 目标容器开辟空间需要从两个容器取较大值
- set_difference返回值既是差集中最后一个元素的位置