STL common algorithms:
Write at the beginning: sort out some algorithms commonly used in stl, involving comparison, exchange, search, traversal, replication, modification, etc. It's worth collecting!!
summary:
- The algorithm is mainly composed of header files < algorithm > < functional > < numeric >.
- < algorithm > is the largest of all STL header files, covering comparison, exchange, search, traversal, copy, modification, etc
- < numeric > is very small and only includes a few template functions that perform simple mathematical operations on the sequence
- < functional > defines some template classes to declare function objects.
1. Common traversal algorithms:
Learning objectives:
- Master common traversal algorithms
Algorithm Introduction:
- for_each / / traverse the container
- transform / / transfer container to another container
1.1 for_each
Function Description:
- Implement traversal container
Function prototype:
-
for_each(iterator beg, iterator end, _func);
//The traversal algorithm traverses the container elements
//beg start iterator
//End end iterator
// _ func function or function object
Example:
#include <algorithm> #include <vector> //Ordinary function void print01(int val) { cout << val << " "; } //Function object class print02 { public: void operator()(int val) { cout << val << " "; } }; //for_ Basic usage of each algorithm void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i); } //inorder traversal for_each(v.begin(), v.end(), print01); cout << endl; for_each(v.begin(), v.end(), print02()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: for_each is the most commonly used traversal algorithm in practical development, which needs to be mastered
1.2 transform
Function Description:
- Transport container to another container
Function prototype:
- transform(iterator beg1, iterator end1, iterator beg2, _func);
//beg1 source container start iterator
//end1 source container end iterator
//beg2 target container start iterator
//_ func function or function object
Example:
#include<vector> #include<algorithm> //Common traversal algorithms 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; //Target container vTarget.resize(v.size()); // The target container needs to open up space in advance transform(v.begin(), v.end(), vTarget.begin(), TransForm()); for_each(vTarget.begin(), vTarget.end(), MyPrint()); } int main() { test01(); system("pause"); return 0; }
Conclusion: the target container to be handled must be opened up in advance, otherwise it cannot be handled normally
2. Common search algorithms:
Learning objectives:
- Master common search algorithms
Algorithm Introduction:
- Find / / find elements
- find_if / / find elements by criteria
- adjacent_find / / find adjacent duplicate elements
- binary_search / / binary search
- Count / / count the number of elements
- count_if / / count the number of elements by condition
2.1 find
Function Description:
- Find the specified element, find the iterator that returns the specified element, and cannot find the return end iterator end()
Function prototype:
-
find(iterator beg, iterator end, value);
//Find the element by value, find the iterator that returns the specified position, and the iterator that returns the end position cannot be found
//beg start iterator
//End end iterator
//value lookup element
Example:
#include <algorithm> #include <vector> #include <string> void test01() { vector<int> v; for (int i = 0; i < 10; i++) { v.push_back(i + 1); } //Find out if there is 5 this element in the container vector<int>::iterator it = find(v.begin(), v.end(), 5); if (it == v.end()) { cout << "Can't find!" << endl; } else { cout << "find:" << *it << endl; } } class Person { public: Person(string name, int age) { this->m_Name = name; this->m_Age = age; } //Heavy load== 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; //Create data 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 << "Can't find!" << endl; } else { cout << "Find name:" << it->m_Name << " Age: " << it->m_Age << endl; } }
Summary: find can find the specified element in the container, and the return value is the iterator
2.2 find_if
Function Description:
- Find elements by criteria
Function prototype:
-
find_if(iterator beg, iterator end, _Pred);
//Find the element by value, find the iterator that returns the specified position, and the iterator that returns the end position cannot be found
//beg start iterator
//End end iterator
// _ Pred function or predicate (returns an imitation function of bool type)
Example:
#include <algorithm> #include <vector> #include <string> //Built in data type 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 << "Can't find!" << endl; } else { cout << "A number greater than 5 was found:" << *it << endl; } } //Custom data type 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; //Create data 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 << "Can't find!" << endl; } else { cout << "Find name:" << it->m_Name << " Age: " << it->m_Age << endl; } } int main() { //test01(); test02(); system("pause"); return 0; }
Summary: find_if search by condition makes the search more flexible, and the provided imitation function can change different strategies
2.3 adjacent_find
Function Description:
- Find adjacent duplicate elements
Function prototype:
-
adjacent_find(iterator beg, iterator end);
//Find adjacent repeating elements and return the iterator at the first position of adjacent elements
//beg start iterator
//End end iterator
Example:
#include <algorithm> #include <vector> 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); //Find adjacent duplicate elements vector<int>::iterator it = adjacent_find(v.begin(), v.end()); if (it == v.end()) { cout << "can't find!" << endl; } else { cout << "The adjacent duplicate element found is:" << *it << endl; } }
Summary: if you find adjacent repeating elements in an interview question, remember to use the adjacent in STL_ Find algorithm
2.4 binary_search
Function Description:
- Finds whether the specified element exists
Function prototype:
-
bool binary_search(iterator beg, iterator end, value);
//Find the specified element and return true, otherwise false
//Note: not available in unordered sequences
//beg start iterator
//End end iterator
//value lookup element
Example:
#include <algorithm> #include <vector> void test01() { vector<int>v; for (int i = 0; i < 10; i++) { v.push_back(i); } //Binary search bool ret = binary_search(v.begin(), v.end(),2); if (ret) { cout << "eureka" << endl; } else { cout << "not found" << endl; } } int main() { test01(); system("pause"); return 0; }
Summary: the binary search method is very efficient. It is worth noting that the elements in the container must be in an orderly sequence
2.5 count
Function Description:
- Number of statistical elements
Function prototype:
-
count(iterator beg, iterator end, value);
//Count the number of occurrences of the element
//beg start iterator
//End end iterator
//Element of value statistics
Example:
#include <algorithm> #include <vector> //Built in data type 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 The number of is: " << num << endl; } //Custom data type 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("wy", 33); Person p2("cdc", 32); Person p3("hw", 44); Person p4("lzh", 19); Person p5("yt", 25); v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); v.push_back(p5); Person p("zh",35); int num = count(v.begin(), v.end(), p); cout << "num = " << num << endl; } int main() { //test01(); test02(); system("pause"); return 0; }
Summary: when counting user-defined data types, it is necessary to overload the operator==
2.6 count_if
Function Description:
- Count the number of elements by condition
Function prototype:
-
count_if(iterator beg, iterator end, _Pred);
//Count the occurrence times of elements by conditions
//beg start iterator
//End end iterator
// _ Pred predicate
Example:
#include <algorithm> #include <vector> class Greater4 { public: bool operator()(int val) { return val >= 4; } }; //Built in data type 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 << "The number greater than 4 is: " << num << endl; } //Custom data type 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("Wang Yuan", 35); Person p2("Juen-Kai Wang", 35); Person p3("Jackson Yee", 35); Person p4("Xiao Zhan", 30); Person p5("Fan Ye", 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 << "Number of children under 35 years old:" << num << endl; } int main() { //test01(); test02(); system("pause"); return 0; }
Summary: count is used for statistics by value and count is used for statistics by condition_ if
3. Common sorting algorithms:
Learning objectives:
- Master common sorting algorithms
Algorithm Introduction:
- Sort / / sort the elements in the container
- random_shuffle / / shuffle the elements within the specified range to randomly adjust the order
- Merge / / merge container elements and store them in another container
- reverse / / reverses the elements of the specified range
3.1 sort
Function Description:
- Sort the elements in the container
Function prototype:
-
sort(iterator beg, iterator end, _Pred);
//Find the element by value, find the iterator that returns the specified position, and the iterator that returns the end position cannot be found
//beg start iterator
//End end iterator
// _ Pred predicate
Example:
#include <algorithm> #include <vector> 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 sorts from small to large by default sort(v.begin(), v.end()); for_each(v.begin(), v.end(), myPrint); cout << endl; //Sort from large to small sort(v.begin(), v.end(), greater<int>()); for_each(v.begin(), v.end(), myPrint); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: sort is one of the most commonly used algorithms in development and needs to be mastered
3.2 random_shuffle
Function Description:
- Shuffle the elements in the specified range to adjust the order randomly
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 <algorithm> #include <vector> #include <ctime> 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; //Disorder order random_shuffle(v.begin(), v.end()); for_each(v.begin(), v.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: random_shuffle shuffle algorithm is more practical. Remember to add random number seeds when using it
3.3 merge
Function Description:
- The two container elements are merged and stored in another container
Function prototype:
-
merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//Container elements are merged and stored in another container
//Note: the two containers must be ordered
//beg1 container 1 start iterator
//end1 container 1 end iterator
//beg2 container 2 start iterator
//end2 container 2 end iterator
//dest destination container start iterator
Example:
#include <algorithm> #include <vector> 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; //The target container needs to open up space in advance vtarget.resize(v1.size() + v2.size()); //Merging requires two ordered sequences merge(v1.begin(), v1.end(), v2.begin(), v2.end(), vtarget.begin()); for_each(vtarget.begin(), vtarget.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: the two containers merged by the merge must have an ordered sequence
3.4 reverse
Function Description:
- Invert the elements in the container
Function prototype:
-
reverse(iterator beg, iterator end);
//Inverts the elements of the specified range
//beg start iterator
//End end iterator
Example:
#include <algorithm> #include <vector> 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 << "Before reversing: " << endl; for_each(v.begin(), v.end(), myPrint()); cout << endl; cout << "After reversal: " << endl; reverse(v.begin(), v.end()); for_each(v.begin(), v.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: reverse reverses the elements in the interval, which may be involved in the interview question
4. Common copy and replacement algorithms:
Learning objectives:
- Master common copy and replacement algorithms
Algorithm Introduction:
- Copy / / copy the elements of the specified range in the container to another container
- replace / / modify the old element of the specified range in the container to a new element
- replace_if / / replace the qualified element in the specified range in the container with a new element
- Swap / / swap elements of two containers
4.1 copy
Function Description:
- Copies the specified range of elements in a container to another container
Function prototype:
-
copy(iterator beg, iterator end, iterator dest);
//Find the element by value, find the iterator that returns the specified position, and the iterator that returns the end position cannot be found
//beg start iterator
//End end iterator
//dest target start iterator
Example:
#include <algorithm> #include <vector> 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() { test01(); system("pause"); return 0; }
Summary: when using copy algorithm to copy, the target container should remember to open up space in advance
4.2 replace
Function Description:
- Modifies the old element of the specified range in the container to a new element
Function prototype:
-
replace(iterator beg, iterator end, oldvalue, newvalue);
//Replace the old element in the interval with a new element
//beg start iterator
//End end iterator
//oldvalue old element
//newvalue new element
Example:
#include <algorithm> #include <vector> 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 << "Before replacement:" << endl; for_each(v.begin(), v.end(), myPrint()); cout << endl; //Replace 20 in the container with 2000 cout << "After replacement:" << endl; replace(v.begin(), v.end(), 20,2000); for_each(v.begin(), v.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: replace will replace the qualified elements in the interval
4.3 replace_if
Function Description:
- Replace the qualified elements in the interval with the specified elements
Function prototype:
-
replace_if(iterator beg, iterator end, _pred, newvalue);
//Replace the element according to the condition, and replace the qualified element with the specified element
//beg start iterator
//End end iterator
// _ pred predicate
//New element replaced by newvalue
Example:
#include <algorithm> #include <vector> 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 << "Before replacement:" << endl; for_each(v.begin(), v.end(), myPrint()); cout << endl; //Replace 30 or more in the container with 3000 cout << "After replacement:" << endl; replace_if(v.begin(), v.end(), ReplaceGreater30(), 3000); for_each(v.begin(), v.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: replace_if search by condition, you can use the imitation function to flexibly filter the satisfied conditions
4.4 swap
Function Description:
- Swap elements of two containers
Function prototype:
-
swap(container c1, container c2);
//Swap elements of two containers
//c1 container 1
//c2 container 2
Example:
#include <algorithm> #include <vector> 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 << "Before exchange: " << endl; for_each(v1.begin(), v1.end(), myPrint()); cout << endl; for_each(v2.begin(), v2.end(), myPrint()); cout << endl; cout << "After exchange: " << endl; swap(v1, v2); for_each(v1.begin(), v1.end(), myPrint()); cout << endl; for_each(v2.begin(), v2.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: when swap containers, pay attention to the same type of containers to be exchanged
5. Common arithmetic generation algorithms:
Learning objectives:
- Master common arithmetic generation algorithms
be careful:
- The arithmetic generation algorithm belongs to a small algorithm. When used, the header file included is #include < numeric >
Algorithm Introduction:
-
Calculate / / calculate the cumulative sum of container elements
-
fill / / add element to container
5.1 accumulate
Function Description:
- Calculate the cumulative sum of interval content container elements
Function prototype:
-
accumulate(iterator beg, iterator end, value);
//Calculate cumulative sum of container elements
//beg start iterator
//End end iterator
//Value starting value
Example:
#include <numeric> #include <vector> 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() { test01(); system("pause"); return 0; }
Summary: when using accumulate, the header file should be numeric. This algorithm is very practical
5.2 fill
Function Description:
- Fills the container with the specified element
Function prototype:
-
fill(iterator beg, iterator end, value);
//Fill the container with elements
//beg start iterator
//End end iterator
//Value padded value
Example:
#include <numeric> #include <vector> #include <algorithm> class myPrint { public: void operator()(int val) { cout << val << " "; } }; void test01() { vector<int> v; v.resize(10); //fill fill(v.begin(), v.end(), 100); for_each(v.begin(), v.end(), myPrint()); cout << endl; } int main() { test01(); system("pause"); return 0; }
Summary: fill can be used to fill the elements in the container interval with the specified value
6. Common set algorithms
Learning objectives:
- Master common set algorithms
Algorithm Introduction:
-
set_intersection / / find the intersection of two containers
-
set_union / / find the union of two containers
-
set_difference / / find the difference between two containers
6.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: the two sets must be an ordered sequence
//beg1 container 1 start iterator
//end1 container 1 end iterator
//beg2 container 2 start iterator
//end2 container 2 end iterator
//dest destination container start iterator
Example:
#include <vector> #include <algorithm> 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; //Take the smaller of the two values to make room for the target container vTarget.resize(min(v1.size(), v2.size())); //Returns the iterator address of the last element of the destination container 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(); system("pause"); return 0; }
Summary:
- Find the ordered sequence of two sets of intersection
- The target container needs to take a small value from the two containers to open up space
- set_ The return value of intersection is the position of the last element in the intersection
6.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);
//Find the union of two sets
//Note: the two sets must be an ordered sequence
//beg1 container 1 start iterator
//end1 container 1 end iterator
//beg2 container 2 start iterator
//end2 container 2 end iterator
//dest destination container start iterator
Example:
#include <vector> #include <algorithm> 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; //Take the sum of the two containers to make room for the target container vTarget.resize(v1.size() + v2.size()); //Returns the iterator address of the last element of the destination container 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(); system("pause"); return 0; }
Summary:
- An ordered sequence of two sets of union sets
- The target container needs to add two containers to open up space
- set_ The union return value is the position of the last element in the union set
6.3 set_difference
Function Description:
- Find the difference set of two sets
Function prototype:
-
set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);
//Find the difference set of two sets
//Note: the two sets must be an ordered sequence
//beg1 container 1 start iterator
//end1 container 1 end iterator
//beg2 container 2 start iterator
//end2 container 2 end iterator
//dest destination container start iterator
Example:
#include <vector> #include <algorithm> 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; //Take the larger of the two values to make room for the target container vTarget.resize( max(v1.size() , v2.size())); //Returns the iterator address of the last element of the destination container cout << "v1 And v2 The difference set of is: " << 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 And v1 The difference set of is: " << 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(); system("pause"); return 0; }
Summary:
- The two sets of difference sets must be ordered sequences
- The target container needs to take a larger value from two containers to open up space
- set_ The return value of difference is the position of the last element in the difference set
Write at the end:
Attach a picture. If you have a problem, issue it directly!! Slip away, slip away~~