preface:
In this note, I annotated most of the code. Some of my ideas and comments were marked in blue, and the key points and areas needing attention were marked in red.
In this article, we mainly introduce the algorithms in STL.
Text:
1. STL algorithm classification
Algorithms in STL can be roughly divided into the following seven categories:
Invariant sequence algorithm
Variable value algorithm
Deletion algorithm
Variable order algorithm
Sorting algorithm
Ordered interval algorithm
Numerical algorithm
2. STL algorithm
Most overload algorithms have two versions
Use "= =" to judge whether the elements are equal, or use "<" to compare the size
One more type parameter "pred" and function parameter "pred op":
By judging the return value of the expression "op(x,y)": true/false
To determine whether x is "equal to" Y, or whether x is "less than" y
If there are two versions of min_element:
iterator min_element(iterator first, iterator last);
iterator min_element(iterator first, iterator last, Pred op);
(in fact, there is one more comparison rule to be passed in)
2.1. Invariant sequence algorithm
This kind of algorithm will not modify the container or object used by the algorithm
Applies to sequential and associative containers
Time complexity is O(n)
min: find the smaller of the two objects (the comparator can be customized)
max: find the larger of the two objects (you can customize the comparator)
min_element: find the minimum value in the interval (the comparator can be customized)
max_element: find the maximum value in the interval (the comparator can be customized)
for_each: do some operation on each element in the interval
count: the number of elements equal to a certain value in the calculation interval
count_if: calculate the number of elements that meet certain conditions in the interval
Find: find the element equal to a certain value in the interval
find_if: find elements that meet certain conditions in the interval
find_end: find the position of the last occurrence of another interval in the interval (the comparator can be customized)
find_first_of: find the first element appearing in another interval in the interval (the comparator can be customized)
adjacent_find: find the position where two consecutive equal elements appear for the first time in the interval (the comparator can be customized)
search: find the position of the first occurrence of another interval in the interval (the comparator can be customized)
search_n: Find n consecutive elements equal to a certain value for the first time in the interval (the comparator can be customized)
Equal: judge whether the two intervals are equal (the comparator can be customized)
mismatch: compare the elements of two intervals one by one, and return the position of the two elements that are unequal for the first time (the comparator can be customized)
lexicographical_compare: compare the size of two intervals in dictionary order (the comparator can be customized)
find:
template<class init, class T>
init find(init first, init last, const T& val);
Return iterator i in [first, last], so that * i==val
find_if:
templast<class init, class Pred>
init find_if(init first, init last, pred pr);
Returns the iterator i in the interval [first, last], so that pr(*i)==true
(so the pr passed in is a function? Check it out. It is a unary predicate, that is, a function object with only one parameter and the return value is limited to bool)
for_each:
template<class init, class Fun>
Fun for_each(init first, init last, Fun f);
For each element e in [first, last], execute f(e), requiring that f(e) cannot change e
count:
template<class init, class T>
size_t count(init first, init last, const T& val);
Calculate the number of elements equal to val in [first, last] (x==y is true)
count_if:
template<class init, class Pred>
size_t count_if(init first, init last, Pred pr);
Calculate the number of elements e conforming to pr(e)==true in [first, last]
(the usage feels similar to find_if)
min_element:
template<class Fwdlt>
Fwdlt min_element(Fwdlt first, Fwdlt last);
Returns the iterator of the smallest element in [first, last], with "<" as the comparator
The smallest means that no element is smaller than it, not that it is smaller than other different elements
Because even a= b. A < B and B < A may not be true
max_element:
template<class Fwdlt>
Fwdlt max_element(Fwdlt first, Fwdlt last);
Returns the iterator of the largest element (not less than any other element) in [first, last]
It also uses "<" as the comparator
Example:
1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 class A 5 { 6 public: 7 int n; 8 A(int i):n(i){} 9 }; 10 bool operator<(const A & a1, const A & a2) 11 { 12 cout<<"< called"<<endl; 13 if (a1.n==3&&a2.n==7) 14 { 15 return true; 16 } 17 return false; 18 } 19 int main(int argc, char const *argv[]) 20 { 21 A aa[] = {3,5,7,2,1}; 22 cout<<min_element(aa,aa+5)->n<<endl; 23 cout<<max_element(aa,aa+5)->n<<endl; 24 return 0; 25 } 26 /* 27 Output: 28 < called 29 < called 30 < called 31 < called 32 3 33 < called 34 < called 35 < called 36 < called 37 7 38 */
(here, suppose the first element is the minimum value, and then compare it one by one. It is found that the first element is really the minimum value under the defined "<", and the result is 3. In the second case, it is found that 3 < 7, and the result is 7)
2.2. Variable value algorithm
Such algorithms modify the values of the elements of the source interval or the target interval
The interval in which the value is modified cannot belong to the associated container (because if it is modified, the order of the associated container will be broken)
for_each: do some operation on each element in the interval (different from the previous one is whether the passed function parameter is const)
Copy: copy an interval elsewhere
copy_backward: copy an interval to another place, but the target interval is modified from back to front
transform: copy elements from one interval to another after deformation
swap_ranges: exchange the contents of two intervals
Fill: fill the interval with a value
fill_n: Replace n elements in the interval with a value
Fill the result of an operation with generate
generate_n: Replace n elements in the interval with the result of an operation
Replace: replace a value in the interval with another value
replace_if: replace the value that meets certain conditions in the interval with another value
replace_copy: copy an interval to another interval. When copying, a value should be copied with a new value
replace_copy_if: copy an interval to another interval. When copying, the value that meets certain conditions shall be replaced with a new value and copied
transform:
template<class init, class Outit, class Unop>
Outit transform(init first, init last, outit x, Unop uop);
For each iterator l in [first, last),
Execute uop(*i); And put the results in the place starting from x
It is required that uop(*i) shall not change the value of * i
The return value of this template is an iterator, i.e. x + (last first)
x can be equal to first
Example: (including some things that have not been mentioned before and)
1 #include<vector> 2 #include<iostream> 3 #include<numeric> 4 #include<list> 5 #include<algorithm> 6 #include<iterator> 7 using namespace std; 8 class CLessThen9 9 { 10 public: 11 bool operator()(int n){return n < 9;} 12 }; 13 void outputSquare(int value){cout<<value*value<<" ";} 14 int calculateCube(int value){return value*value*value;} 15 16 int main(int argc, char const *argv[]) 17 { 18 const int SIZE = 10; 19 int a1[] = {1,2,3,4,5,6,7,8,9,10}; 20 int a2[] = {100,2,8,1,50,3,8,9,10,2}; 21 vector<int> v(a1,a1+SIZE); 22 ostream_iterator<int> output(cout," "); 23 random_shuffle(v.begin(),v.end());//Randomly disrupt the value of the interval 24 cout<<endl<<"1)";//Output: 1)9 2 10 3 1 6 8 4 5 7((random here) 25 copy(v.begin(),v.end(),output); 26 copy(a2,a2+SIZE,v.begin()); 27 cout<<endl<<"2)";//Output: 2)2 28 cout<<count(v.begin(),v.end(),8); 29 cout<<endl<<"3)";//Output: 3)6 30 cout<<count_if(v.begin(),v.end(),CLessThen9());//The object is called here 31 cout<<endl<<"4)";//Output: 4)1 32 cout<<*(min_element(v.begin(),v.end())); 33 cout<<endl<<"5)";//Output: 5)100 34 cout<<*(max_element(v.begin(),v.end())); 35 cout<<endl<<"6)";//Output: 6)193 36 cout<<accumulate(v.begin(),v.end(),0);//Sum and add up to 0 37 cout<<endl<<"7)";//Output: 10000 4 64 1 2500 9 64 81 100 4 38 for_each(v.begin(),v.end(),outputSquare); 39 vector<int> cubes(SIZE); 40 transform(a1,a1+SIZE,cubes.begin(),calculateCube);//a1 Where's the cube cubes inside 41 cout<<endl<<"8)";//Output: 1 8 27 64 125 216 343 512 729 1000 42 copy(cubes.begin(),cubes.end(),output); 43 44 return 0; 45 }
Of which:
ostream_iterator<int> output(cout," ");
An ostream is defined_ Iterator < int > object, which can output integers divided by "" (space) through cout
copy(v.begin(),v.end(),output);
The content that causes v is output on cout
(the teacher played impassioned music when he talked here)
copy:
template<class init, class outit>
outit copy(init first, init last, outit x);
This function executes * (x+N) = *(first+N) for each N in the interval [0, last first), and returns x+N
For copy(v.begin(),v.end(),output);
The types of first and last are vector < int >:: const_ iterator
The type of output is ostream_ iterator<int>
copy source code
1 template<class _ll, class _ol> 2 inline _ol copy(_ll _F,_ll _L,_ol _X) 3 { 4 for (;_F != _L; ++_X,++_F) 5 *_X = *_F; 6 return(_X); 7 }
A question, how to write my in the following program_ ostream_ iterator?
1 #include<iostream> 2 #include<fstream> 3 #include<string> 4 #include<algorithm> 5 #include<iterator> 6 using namespace std; 7 int main(int argc, char const *argv[]) 8 { 9 int a[4] = {1,2,3,4}; 10 My_ostream_iterator<int> oit(cout,"*"); 11 copy(a,a+4,oit);//Output 1*2*3*4* 12 ofstream oFile("test.txt",ios::out); 13 My_ostream_iterator<int> oitf(oFile,"*"); 14 copy(a,a+4,oitf);//towards text.txt Write 1 to file*2*3*4 15 oFile.close(); 16 return 0; 17 }//How to write My_ostream_iterator???
After instantiating the "copy(a,a+4,oit)" in the above program, we get copy as follows:
1 template<class _ll, class _ol> 2 inline My_ostream_iterator<int> copy(int _F,int _L,My_ostream_iterator<int> _X) 3 { 4 for (;_F != _L; ++_X,++_F) 5 *_X = *_F; 6 return(_X); 7 }
My_ ostream_ The iterator class should overload the "+ +" and "*" operators
"=" should also be overloaded
1 #include<iterator> 2 #include<iostream> 3 #include<string> 4 template<class T> 5 class My_ostream_iterator:public iterator<output_iterator_tag, T> 6 { 7 private: 8 string sep;//Separator 9 ostream & os; 10 public: 11 My_ostream_iterator(ostream & o,string s):sep(s),os(o){} 12 void operator++(){};//++You only need to have a definition, and you don't need to do anything 13 My_ostream_iterator & operator*(){return *this;} 14 My_ostream_iterator & operator=(const T & val) 15 { os<<val<<sep;return *this;} 16 };
(io Liu stunned me 555)
Postscript:
This class is so long. Next time I see such a long class, I will.... After reading it, I can't help learning, right? Don't say it. Happy new year, everyone. I wish you good luck!