STL
Standard Template Library
Six components
- Containers: storing data
- Algorithm: operation data
- Iterator: the algorithm operates on container data through iterator
- Imitation function: provide more strategies for algorithms
- Adapter: an interface that provides more parameters for the algorithm
- Space configurator: dynamically allocate and manage space for algorithms and containers
Important feature: separation of data and operation. The data is managed by the container, and the operation is completed by a specific algorithm. Container and iterator correspond one-to-one
Algorithms are divided into qualitative and non qualitative algorithms:
Qualitative change algorithm: the content of elements in the interval will be changed during the operation, such as copying, replacing, deleting, etc;
Non Prime algorithm: the contents of elements in the interval will not be changed during the operation, such as searching, counting, traversing, searching for extreme values, etc;
string class
string encapsulates char *, which is used to manage strings. It is a char type container
The string class automatically manages the memory allocated by char *. Regardless of memory release and out of bounds, every time a string is copied, the string class is responsible for maintenance
string constructor
string();//Create an empty string, for example: string str; string(const string& str);//Initialize another string object with one string object string(const char* s);//Initialize with string s string(int n, char c);//Initialize with n characters c
string basic assignment operation
string& operator=(const char* s);//char * type string is assigned to the current string string& operator=(const string &s);//Assign the string s to the current string string& operator=(char c);//Character assigned to the current string string& assign(const char *s);//Assign the string s to the current string string& assign(const char *s, int n);//Assign the first n characters of string s to the current string string& assign(const string &s);//Assign the string s to the current string string& assign(int n, char c);//Assign n characters c to the current string string& assign(const string &s, int start, int n);//Assign s (n characters from start) to the string
string access character operation
char& operator[](int n);//Take characters by [] method char& at(int n);//Get characters through the at method string str = "helloc"; str[1] = 'E'; str.at(1) = 'E';
In QT, [] will not throw an exception if it crosses the boundary, and the at method will throw an exception if it crosses the boundary. [] execute str[7] = 'A' to output Hello C normally
string splicing operation
string& operator+=(const string& str);//Overload + = operator string& operator+=(const char* str);//Overload + = operator string& operator+=(const char c);//Overload + = operator string& append(const char *s);//Connect the string s to the end of the current string string& append(const char *s, int n);//Connect the first n characters of the string s to the end of the current string string& append(const string &s);//Same as operator + = () string& append(const string &s, int pos, int n);//Connect the n characters from pos in the string s to the end of the current string string& append(int n, char c);//Add n characters c at the end of the current string
Find and replace string
int find(const string& str, int pos = 0) const; //Find the location where str first appears, starting from pos int find(const char* s, int pos = 0) const; //Find the location where s first appears, starting from pos int find(const char* s, int pos, int n) const; //Find the first position of the first n characters of s from pos position int find(const char c, int pos = 0) const; //Find the position where the character c first appears int rfind(const string& str, int pos = npos) const;//Find the last position of str, starting from pos int rfind(const char* s, int pos = npos) const;//Find the last position of s, starting from pos int rfind(const char* s, int pos, int n) const;//Find the last position of the first n characters of s from pos int rfind(const char c, int pos = 0) const; //Find the last occurrence of the character c string& replace(int pos, int n, const string& str); //Replace n characters from pos to str string& replace(int pos, int n, const char* s); //Replace the n characters starting from pos with the string s
string compare operation
//The compare function returns 1 when >. int compare(const string &s) const;//Compare with string s int compare(const char *s) const;//Compared with the string s, the > < = = equality operator is overloaded
string substring
string substr(int pos = 0, int n = npos) const;//Returns a string of n characters starting with pos
string insert and delete operations
string& insert(int pos, const char* s); //Insert string string& insert(int pos, const string& str); //Insert string string& insert(int pos, int n, char c);//Inserts n characters c at the specified position string& erase(int pos, int n = npos);//Delete n characters from Pos
String and c-style string conversion
//string to char* string str = "itcast"; const char* cstr = str.c_str(); //char * to string char* s = "itcast"; string str(s);
vector container
vector is similar to array, and its biggest feature is the flexible use of space
vector single end operation, can only be added or deleted at one end
v.begin(): get the starting iterator of the container (point to the 0th element)
v.end(): get the end iterator of the container (point to the next position of the last element)
Data structure of vector
Linear continuous space, the two iterators Myfirst and Mylast point to the currently used range, iterator_ Myend points to the end of the whole contiguous memory
In case of need, the actual configured size of the vector may be larger than the required size. Once the capacity is full, the entire vector needs to find a larger continuous space, and then copy the data. And all the original iterators fail
vector constructor
vector<T> v; //The template implementation class is adopted for implementation, and the default constructor is vector(v.begin(), v.end());//Copy the elements in the v[begin(), end()) interval to itself. vector(n, elem);//The constructor copies n elem s to itself. vector(const vector &vec);//Copy constructor.
iterator
vector<int>::iterator it = v.begin();//Define an iterator to save the starting iterator for(; it!=v.end();it++) cout<<*it<<" ";//Traverse container
View vector's memory management mechanism: open up new space
Each time a space is opened: (1) find a new memory; (2) capacity is doubled
vector<int> v; cout<<v.capacity()<<" "<<v.size()<<endl;//Output 0 0 vector<int>::iterator it; for(int i=0; i<5; ++i){ v.push_back(i); if(it != v.begin()){//The v.begin() iterator changes every time. Description: the memory address of the vector has changed cout<<v.capacity()<<endl;//It has been executed for 4 times, outputting 1, 2, 4 and 8 respectively it = v.begin(); } }
Preset space
v.reserve(1000);
Common assignment operations of vector
assign(beg, end);//Assign the data copy in the [beg, end) interval to itself. Here beg and end are iterators assign(n, elem);//Assign n elem copies to itself. vector& operator=(const vector &vec);//Overload the equal sign operator swap(vec);// Interact vec with its own elements, v2.swap(v1); Swap v1 and V2
Traverse container
printVector(vector<int> &v){ vector<int>::iterator it = v.begin(); for(;it!=v.end();it++){ cout<<*it<<" "; } cout<<endl; }
You can also traverse like an array
vector size operation
size(); empty(); resize(int num);//Fill the new location with the default value, which is 0 resize(int num, elem);//Fill the new position with elem capacity(); reserve(int len);//Reserved len element lengths, reserved positions are not initialized, and elements are inaccessible //resize will print a total of num elements, while reserve will only print existing elements
vector data access operation
at(int idx); operator[]; front(); back();
vector insertion and deletion
insert(const_iterator pos, int count, elem);//The iterator points to the position pos and inserts count elem s; pos will be moved back push_back(elem);//Tail insertion pop_back(elem);//Tail delete erase(const_iterator start, const_iterator end);//Interval deletion erase(const_iterator pos);//Delete the element indicated by the iterator clear();//Delete all;
swap shrink space
resize cannot reduce capacity, only change size or increase capacity
vector<int> v; v.reserve(100); vector<int> (v).swap(v);//(v) Represents an anonymous object
v1 is the old object, and vector() is the new anonymous object. Copy construction occurs during the copying of the old object to the anonymous object. Anonymous object copying only copies the interval with data
Then the anonymous object and v exchange, so v only contains the valid data part
The life cycle of the anonymous object is the current statement. After the statement ends, the anonymous object is released
vector container nesting
vector<vector<int>> v;//definition //ergodic vector<vector<int>>::iterator it = v.begin(); for(; it!=v.end(); it++){ vector<int>::iterator mit = (*it).begin(); for(; mit!=(*it).end(); ++mit){ cout<<*mit<<" "; } cout<<endl; }
vector and custom types
Overload operator or set friend
Case: sorting custom types
sort(v1.begin(), v1.end(), comparePerson);//comparePerson is a custom collation
class Person{ friend bool comparePerson(Person ob1, Person ob2); friend void printVector(vector<Person> &v); private: int num; string name; public: Person(int num, string name){ this->num = num; this->name = name; } }; bool comparePerson(Person ob1, Person ob2){ return ob1.num<ob2.num; } void printVector(vector<Person> &v){ vector<Person>::iterator it = v.begin(); for(;it!=v.end();it++){ cout<<(*it).num<<" "<<(*it).name<<endl; } } int main(void){ vector<Person> v; v.push_back(Person(3, "lucy")); v.push_back(Person(7, "bob")); v.push_back(Person(1, "tom")); printVector(v); sort(v.begin(), v.end(), comparePerson);//< algorithm > needs to be introduced printVector(v); return 0; }
deque container
#include <deque>
Difference with vector:
(1) Allow insertion and deletion at both ends (vector s can also be inserted at the head, but the efficiency is extremely poor)
(2) Deque's space is discontinuous and is composed of multiple quantitative continuous spaces. Therefore, deque has no reserve function
(3) The iterator of deque is not an ordinary pointer, and its complexity is higher than that of vector. Vector should be used as much as possible
(4) If necessary, for example, when sorting, deque can be copied to vector, and then copied back after sorting
(5) deque's biggest job is to maintain the integrity of multi segment space and provide random access interfaces. Avoids space reconfiguration, replication and release, but at the cost of complex iterator architecture
deque principle:
Take a map as the central controller
Each map element stores a pointer to a continuous memory space. These contiguous memory spaces are called buffers. The buffer is the storage body of deque
deque constructor
deque <T> deqT; deque(beg, end); deque(n, elem); deque(const deque &deq);
deque assignment operation
assign(beg, end); assign(n, elem); deque& operator=(const deque &deq); swap(dep);
deque size operation
deque.size(); deque.empty(); deque.resize(num);//Default fill deque.resize(num, elem);
deque insert and delete
//Double ended operation push_back(elem);//Tail insertion push_front(elem);//Head insertion pop_back();//Tail delete pop_front();//Head delete //Insertion: pos beg end are iterators insert(pos, elem); insert(pos, n, elem);//Insert n elem s; insert(pos, beg, end); //delete clear(); erase(beg, end); erase(pos);
deque data access
at(idx); operator[]; front();//Return the first element back();//Returns the last element
case
There are 5 contestants: contestant ABCDE. 10 judges will score each contestant separately, remove the highest score, remove the lowest score among the judges, and take the average score.
- Create five players and put them in the vector
- Traverse the vector container, take out each player, execute the for loop, and save the 10 scores into the deque container
- sort algorithm sorts the scores in deque container, pop_back pop_front: remove the highest and lowest scores
- deque container traverses once, accumulating scores, accumulating scores / d.size()
- person.score = average score
#include<iostream> #include<vector> #include<deque> #include<algorithm> #include<time.h> using namespace std; class Person{ friend void showPerson(vector<Person> &v); friend void playGame(vector<Person> &v); private: string name; float score; public: Person(string name, float score){ this->score = score; this->name = name; } }; void showPerson(vector<Person> &v){ vector<Person>::iterator it = v.begin(); for(;it!=v.end();it++){ cout<<(*it).name<<" "<<(*it).score<<endl; } } void createPerson(vector<Person>& v){ string tmpName = "ABCDE"; for(int i=0; i<5; ++i){ string name = "player"; name+=tmpName[i]; v.push_back(Person(name, 0.0f)); } } void playGame(vector<Person> &v){ vector<Person>::iterator it = v.begin(); for(; it!=v.end(); it++){ deque<float> d; for(int i=0; i<10; ++i){ d.push_back((float)(rand()%41+60));//1. Input results } sort(d.begin(), d.end());//2. Sorting d.pop_back(); d.pop_front();//3. Remove the highest and lowest scores (*it).score = (float)accumulate(d.begin(), d.end(), 0)/d.size(); } } int main(void){ vector<Person> v; srand(time(NULL)); createPerson(v);//Create player playGame(v); showPerson(v); return 0; }
stack container
//1. stack constructor stack<T> stkT; stack(const stack &stk); //2. stack assignment stack& operator=(const stack &stk); //3. stack data access push(elem); pop(); top(); //4. stack size operation empty(); size();
queue container
queue does not provide traversal function and iterator
//1. queue constructor queue<T> queT; queue(const queue &que); //2. Assignment of queue queue& operator=(const queue& que); //2. queue data access push(elem);//Add element at the end of the queue pop();//Team leader removal back();//Returns the last element without deleting it front();//Returns the first element, but does not delete it //4. queue size operation empty(); size();
list container
!! The list container is a two-way linked list
The iterator of the list container is a bidirectional iterator, which does not support + n, but supports++
list constructor
list<T> lstT; list(begin, end); list(n, elem); list(const list &lst);
list insert and delete
push_back(elem); pop_back(); push_front(elem); pop_front(); insert(pos, elem); insert(pos, n, elem); insert(pos, beg, end); clear(); erase(beg, end); erase(pos); remove(elem);//Delete all elements matching elem value
list size operation
size(); empty(); resize(num); resize(num, elem);
list assignment operation
assign(beg, end); assign(n, elem); list& operator=(const list &lst); swap(list);
list data access
front(); back();
list reverse data
reverse(); sort();
set/multiset container
!! All elements will be automatically sorted according to the key value of the element. The element of set is both a key value and a real value
set does not allow the same key value
The characteristics and usage of multiset are completely similar to that of set, but multiset allows duplicate key values
The iterator of set is a read-only iterator, and modification of key value is not allowed
set constructor
set<T> st; multiset<T> mst; set(const set &st);
set assignment operation
set& operator=(const set &st); swap(st);
set size operation
size(); empty();
set insert and delete
insert(elem); erase(pos);//pos refers to the iterator, which returns the iterator of the next element erase(beg, end); erase(elem);//Delete the element named elem in the container
To modify the collation, you must modify it before inserting. To use a functor
Functor: a class that overloads the function call operator ()
set lookup operation
find(key);//Find out if the key exists, if there is an iterator that returns the key element, if there is no iterator, return set.end(); cout(key);//Find the number of elements of the key, 0 or 1 lower_bound(keyElem);//Return the element of keyElem. If not, return the iterator at the next position upper_bound(keyElem);//Returns the iterator of the next element of keyelement equal_range(keyElem); //Pay attention to lower_bound,upper_bound,equal_ The iterator returned by range refers to the position, not the size. If there are no qualified ones, return keyElem itself
equal_range returns two iterators, lower_bound and upper_bound, I need to pick it up with pair
//equal_range receives the return value in the form of a pair of groups pair<set<int>::const_iterator, set<int>::const_iterator> pa; pa = st.equal_range(6); cout<<*(pa.first)<<endl; cout<<*(pa.second)<<endl;
Modify collation
//Imitative function: class of overloaded function call calling operator () class MyGreater{ public: bool operator()(int v1, int v2){ return v1>v2; } }; void printSet(set<int, MyGreater> &s){ set<int, MyGreater>::const_iterator it = s.begin(); for(; it!=s.end(); it++){ cout<<*it<<" "; } cout<<endl; } int main(void){ set<int, MyGreater> st; st.insert(7); st.insert(5); st.insert(6); printSet(st); return 0; }
Custom class must modify collation
class MyGreaterPerson; class Person{ friend MyGreaterPerson; friend void printPersonSet(set<Person, MyGreaterPerson> &st); private: int num; string name; public: Person(int num, string name){ this->name = name; this->num = num; } }; //Custom class must modify collation class MyGreaterPerson{ public: bool operator()(Person ob1, Person ob2){ return ob1.num < ob2.num; } }; void printPersonSet(set<Person, MyGreaterPerson> &st){ set<Person, MyGreaterPerson>::const_iterator it = st.begin(); for(; it!=st.end(); it++){ cout<<(*it).num<<" "<<(*it).name<<endl; } } int main(void){ set<Person, MyGreaterPerson> st2; st2.insert(Person(9, "lucy")); st2.insert(Person(4, "bob")); st2.insert(Person(7, "tom")); printPersonSet(st2); return 0; }
pair group
pair<int, string> p1(10086, "move"); pair<int, string> p2 = make_pair(110, "call the police");//recommend cout<<p2.first<<endl; cout<<p2.second<<endl;
map/multimap container
All elements of the map are pairs. The first element of pair is a key value, and the second element is a real value;
map does not allow the same key value, and the key value is automatically sorted
You cannot modify the key value of the map through the iterator, but you can modify the real value
The only difference between multimap and map is that the key value of multimap can be repeated
Both multimap and map are implemented with red black trees
map constructor
map<T1, T2> mapTT; map(const map &mp);
map assignment operation
map& operator=(const map &mp); swap(map);
map size operation
size(); empty();
map insert and delete
//Inserting through pair insert(pair<T1, T2>(elem1, elem2)); insert(make_pair(elem1, elem2)); //By value_type insert insert(map<T1, T2>::value_type(elem1, elem2)); //Insert by array mp[key] = value; //delete clear(); erase(pos); erase(beg, end); erase(keyElem);//Delete the pair group whose key is keyelement in the container
map lookup operation
find(key);//Find whether the key exists. If it exists, return the element iterator. If it does not exist, return map.end(); count(keyElem);//Calculate the number of pairs whose key is keyelement; It is 0 or 1 for a map, and may be greater than 1 for multiple multimap s lower_bound(keyElem); upper_bound(keyElem); equal_range(keyElem);//These three functions have the same meaning as set
!! It is dangerous to use the array method to operate the map. If it does not exist, a key will be automatically created
5 people, 3 departments, required to show people by Department
Idea: vector stores information of 5 people
The multimap stores the pair (Department, vector.iterator) of the group
Find: find the starting iterator of the Department in the multimap
Count: count the number of people in the Department
Usage scenarios of each container
- Usage scenario of vector: for example, in the storage of historical operation records of software, we often need to view historical records, such as the last record and the last record, but we do not delete records, because records are descriptions of facts.
- Use scenario of deque: for example, in the queuing ticketing system, deque can be used for the storage of queuers, supporting the rapid removal of the head end and the rapid addition of the tail end. Deque supports fast insertion and removal of the head, which is the advantage of deque.
- Use scenario of the list: for example, the storage of bus passengers, passengers may get off at any time, and frequent removal and insertion of uncertain location elements are supported.
- Use scenario of set: for example, for the storage of personal score records of mobile games, the storage requirements are arranged in order from high scores to low scores.
- Usage scenario of map: for example, 100000 users are stored by ID number. If you want to quickly find the corresponding users by ID. Map uses binary tree, which has fast searching efficiency. If it is a vector container, in the worst case, you may have to traverse the entire container to find the user.
STL algorithm
functor
To use a class like a function call, you need to override the () operator
class Print{ public: void operator()(char *str){ cout<<str<<endl; } }; void test(){ Print ob; ob("helloc!");//Rewrite the () operator to form a form of function call, which is called a function object (functor) }
If a function object has one parameter, it is called a unary function object
If a function object has two parameters, it is called a binary function object
If a function object has multiple parameters, it is called a multivariate function object
Function objects usually do not define constructors and destructors, so there will be no problems in construction and destruction
Function objects go beyond the concept of ordinary functions. Function objects can have their own states
Function objects can be compiled inwardly with good performance. It is almost impossible to use function pointers
The function object can adopt template function to make it universal
Predicate (modify rule)
Ordinary functions or functors whose return value type is bool are called predicates
If the predicate has one parameter, it is called a unary predicate
If the predicate has two parameters, it is called a binary predicate
- one-element predicate
bool over30(int value){ return value > 30; } class Over30{ public: bool operator()(int value){ return value > 30; } }; //General function providing strategy ret = find_if(v.begin(), v.end(), over30); //Provision strategy of functor ret = find_if(v.begin(), v.end(), Over30());//Form an anonymous object
- two-place predicate
bool over30(int v1, int v2){ return v1 > v2; } class Over30{ public: bool operator()(int v1, int v2){ return v1 > v2; } }; //General function providing strategy sort(v.begin(), v.end(), over30); //Provision strategy of functor sort(v.begin(), v.end(), Over30());
Built in function object
STL has built-in function objects. The objects generated by these functions are the same as general functions
- 6 arithmetic class function objects
template<class T> T plus<T>//Additive functor template<class T> T minus<T>//Subtractive functor template<class T> T multiplies<T>//Multiplicative functor template<class T> T divides<T>//Division functor template<class T> T modulus<T>//Take imitation function template<class T> T negate<T>//Take inverse function
- 6 relational operation class function objects, each of which is binary operation
template<class T> bool equal_to<T>//be equal to template<class T> bool not_equal_to<T>//Not equal to template<class T> bool greater<T>//greater than template<class T> bool greater_equal<T>//Greater than or equal to template<class T> bool less<T>//less than template<class T> bool less_equal<T>//Less than or equal to
- Logical operation, not is unary, and the rest is binary operation
template<class T> bool logical_and<T>//Logic and template<class T> bool logical_or<T>//Logical or template<class T> bool logical_not<T>//Logical non
- use
sort(v.begin(), v.end(), greater<int>());//You can rewrite and modify rules by using built-in functions instead of using generic functions ret = find_if(v.begin(), v.end(), bind2nd(greater<int>(),10));//find_if has only three parameters, so it needs to be bound with bind
Adapter
function object adaptor
class PrintInt{ public: void operator()(int val){ cout<<val+100<<" "; } }; for_each(v.begin(), v.end(), PrintInt());//Custom rules required cout<<endl;
Further: binding parameters
//2. Public inheritance (binary)_ Function parameter extraction class PrintInt:public binary_function<int, int, void>{ public: //3. Modify operator() with const void operator()(int val, int tmp) const{ cout<<val+tmp<<" "; } }; void test(){ vector<int> v; v.push_back(10); v.push_back(6); v.push_back(20); //1. bind2nd or bind1st binding parameters for_each(v.begin(), v.end(), bind2nd(PrintInt(), 200)); cout<<endl; }
bind1st is bound to the first parameter val, and bind2nd is bound to the second parameter tmp
function pointer adaptor
void myPrintInt(int value, int tmp){ cout<<value+tmp<<" "; } for_each(v.begin(), v.end(), bind2nd(ptr_fun(myPrintInt), 200)); cout<<endl;
Member functions as adapters
class Data{ public: void printInt(int tmp){ cout<<value+tmp<<" "; } } for_each(v.begin(), v.end(), bind2nd(mem_fun_ref(&Data::printInt), 100));
Reverse Adapter
- Negate one yuan
ret = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 30)));//Find the first less than or equal to 30
- Binary negation
//lambda expression, supported from c++11 //[] lambda cannot be read or written; [=] lambda reads data; [&] lambda reads and writes data // for_each(v.begin(), v.end(), [&](int val){ cout<<val<<" "; }); cout<<endl; sort(v.begin(), v.end(), not2(greater<int>()));//greater requires two parameter comparisons, so use not2
Common algorithms
for_each
for_each(iterator beg, iterator end, _callback);
transform
Move the specified container interval element to another container
transform does not allocate memory to the target container, so it needs to allocate memory in advance
@param beg1 source container start iterator
@param end1 source container end iterator
@param beg2 target container start iterator
@param _cakkback callback function or function object
@return "returns the target container iterator."
transform(iterator beg1, iterator end1, iterator beg2, _callback);
int myTransform(int value){ return value; } v2.resize(v1.size()); transform(v1.begin(), v1.end(), v2.begin(), myTransform);
find
find(iterator beg, iterator end, iterator, value);//Return v.end() not found
find_if
find_if(iterator beg, iterator end, _callback);//Condition search ret = find_if(v.begin(), v.end(), bind2nd(greater<int>(),30));//Cannot find the returned v.end();
adjacent_find
//@Return returns the iterator of the first position of the adjacent element adjacent_find(iterator beg, iterator end, _callback);
binary_search
//Binary search must be orderly bool binary_search(iterator beg, iterator end, value);
count
//Count the number of occurrences of the element, and return int count(iterator beg, iterator end, value);
count_if
//Find by criteria count_if(iterator beg, iterator end, _callback); count_if(v.begin(), v.end(), bind2th(greater<int>(), 10));//Returns the number greater than 10
Common sorting algorithms
merge
//Merge and store two containers into another container //It is necessary to open up space for the third container in advance merge(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest);//dest target container start iterator
sort
sort(iterator beg, iterator end, _callback);
random_shuffle
//Randomly adjust the order of elements within the specified range random_shuffle(iterator beg, iterator end); //use srand(time(NULL)); random_shuffle(v.begin(), v.end());
reverse
reverse(iterator beg, iterator end);
Common copy replacement algorithms
copy
//Copy: copy the data in one container to another, but will not automatically allocate memory copy(iterator beg, iterator end, iterator dest.beg);
Copy to terminal
copy(iterator beg, iterator end, ostream_iterator<int>(cout, " "));//'' is a connector
replace
replace(iterator beg, iterator end, oldValue, newValue); replace(v.begin(). v.end(), 30, 3000);//Replace 30 with 3000
replace_if
replace_if(iterator beg, iterator end, _callback, newValue);
Examples:
class Greater30{ public: bool operator()(int val){ return val>30; } }; replace_if(v.begin(), v.end(), Greater30(), 2000);//In addition to imitation functions, you can also use built-in functions, ordinary functions, etc
swap
swap(container c1, container c2);//Swap two containers
Common arithmetic generation algorithm
accumulate
//Cumulative summation accumulate(iterator beg, iterator end, value);//Value means the value after cumulative summation plus value
fill
fill(iterator beg, iterator end, value);//Fill interval value with value
Common set algorithm
set_intersection
//Find the intersection of two sets and save the result in another set //The set must be an ordered sequence set_intersection(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest.beg);
Examples:
v3.resize(min(v1.size(), v2.size())); vector<int>::iterator ret; ret = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), v3.begin()); copy(v3.begin(), ret, ostream_iterator<int>(cout, " ")); cout<<endl;
set_union
//Set union set set_union(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest.beg);
set_difference
//Set difference set set_difference(iterator beg1, iterator end1, iterator beg2, iterator end2, iterator dest.beg);