One of the purposes of writing this sharing is to write a summary so that you can review it at any time in the future. Another is to introduce what STL is and how to use STL to solve problems more efficiently and lazily to those Mengxin who don't know much about STL. This article will be updated for a long time. You are welcome to supervise your study together. If you have mistakes or need to add, you are welcome to leave a message in the comment area~ Jump to AcWing~
1, What is STL?
STL(Standard Template Library) is a general term for a series of software developed by HP Labs. Now it mainly appears in C + +. STL is broadly divided into container, algorithm and iterator. Almost all STL codes adopt template classes or template functions, which provides better code reuse opportunities than the traditional library composed of functions and classes.
2, What are the six components of STL?
STL provides six components that can be combined and applied to each other. These six components are container, algorithm, iterator, functor, adapter and space configurator. Among them, the most used in the algorithm competition are containers, algorithms and iterators.
- Container: STL containers are various data structures, such as vector, stack, queue, map, set, etc., used to store data. From the implementation point of view, STL containers are a kind of class template.
- Algorithm: most STL algorithms are defined in the < algorithm > header file, including various commonly used algorithms, such as sort, find, copy, reverse, etc. from the implementation point of view, STL algorithm is a function template.
- Iterator: STL iterators act as the glue between containers and algorithms. There are five types. From the implementation point of view, iterators are class template s that overload pointer related operations such as opetator *, opetator - >, operator + +. All stl containers come with their own iterators. Only the designer of the container knows how to traverse its own elements.
- Functor: it behaves like a function and can be used as a strategy of the algorithm. From the implementation point of view, a functor is a class or class template that overloads operator().
- Adapter: something used to decorate the interface of a container or functor or iterator.
- Space allocator: responsible for space configuration and management. From the implementation point of view, the configurator is a class template that implements dynamic space configuration, space management and space release.
3, STL container details
I believe that many people learn STL in order to better install B in the competition, use various data structures and algorithms, and improve the speed of problem solving. Indeed, using containers in STL can define various data structures without handwriting, and using algorithms in STL can implement various basic algorithms without handwriting. Therefore, this part is the most important part for algorithm giants. What are stl containers? How to use it in doing questions?
① Vector: also known as variable length array, defined in the < vector > header file. The vector container is a dynamic space. With the addition of elements, its internal mechanism will automatically expand the space to accommodate new elements. Therefore, the use of vector is of great help to the rational utilization and flexibility of memory.
- How vector is defined
vector<int> v;//Define a vector in which the element is of type int vector<int> v[N];//Define a vector array with N vectors vector<int> v(len);//Define a vector with length len vector<int> v(len, x);//Define a vector with length len and initialize each element as x vector<int> v2(v1);//Assign a value to v2 with v1. The type of V1 is vector vector<int> v2(v1.begin(), v1.begin() + 3);//Assign the third element 0 ~ 2 in v1 to v2
- Common built-in functions of vector
//Common built-in functions in vector vector<int> v = { 1, 2, 3 };//Initialize vector, v:{1, 2, 3} vector<int>::iterator it = v.begin();//Defines the iterator of the vector, pointing to begin() v.push_back(4);//Insert element 4, v:{1, 2, 3, 4} at the end of the vector v.pop_back();//Delete the last element of the vector, v:{1, 2, 3} v.size();//Returns the number of elements in the vector v.empty();//Returns whether the vector is empty. If it is empty, it returns true. Otherwise, it returns false v.front();//Returns the first element in the vector v.back();//Returns the last element in the vector v.begin();//Returns the iterator of the first element of the vector v.end();//Returns the iterator at the position after the last element of the vector v.clear();//Empty vector v.erase(v.begin());//Delete the element pointed to by the iterator it v.insert(v.begin(), 1);//Insert element 1 before the position pointed to by iterator it //Traversal by subscript for (int i = 0; i < v.size(); i++) cout << v[i] << ' '; //Traversal using iterators for (vector<int>::iterator it = v.begin(); it != v.end(); it++) cout << *it << ' '; //for_each traversal (C++11) for (auto x : v) cout << x << ' ';
② Stack: also known as stack, it is a Last In First Out (LIFO) data structure. It is defined in the < stack > header file. The stack container allows adding elements, removing elements and obtaining stack top elements. However, except for the top, there is no way to access other elements of the stack. In other words, the stack is not allowed to traverse.
- How stack is defined
stack<int> stk;//Define a stack where the element type is int stack<int> stk[N];//Define a stack array with N stacks
- Common built-in functions of stack
//Common built-in functions in stack stack<int> stk; stk.push(x);//Insert element x in stack stk.pop();//Pop up the top element of stack stk.top();//Returns the top element of the stack stk.size();//Returns the number of elements in the stack stk.empty();//Returns whether the stack is empty. If it is empty, it returns true. Otherwise, it returns false
③ String: also known as string, defined in the < string > header file. C-style strings (character arrays ending with null characters) are too complex to master, so the C + + standard library defines a string class. String played well. TIANTI and Lanqiao really had a hand in winning a national award. Last year, when I was a sophomore, I learned algorithms from scratch. I didn't learn much in two weeks, only learned string, and the school selection entered the top few. Later, I won some small awards in the national competition, and then ACM was blasted (crying). Therefore, it is important to use string skillfully~
- How string is defined
string str;//Define an empty string string str[N];//Define a string array with N strings string str(5, 'a');//Initialize with 5 characters' a ' string str("abc");//Use string initialization
- Common built-in functions of string
//Common built-in functions in string string str("abcabc"); str.push_back('d');//Insert the character "abcabcd" at the end of the string str.pop_back();//Delete the character at the end of the string, "abcabc" str.length();//Returns the number of characters in a string str.size();//The function is the same as length() str.empty();//Returns whether the string is empty. If it is empty, it returns true. Otherwise, it returns false str.substr(1);//Returns the substring from subscript 1 to the end of string, "bc" str.substr(0, 2);//Returns a substring of length 2 from subscript 0 in string, "ab" str.insert(1, 2, 'x');//Insert 2 characters' x 'and "axxbcac" before the character with subscript 1 str.insert(1, "yy");//Insert the string "yy", "ayyxxbcac" before the character with subscript 1 str.erase(1, 4);//Delete 4 characters from position 1, "abcabc" str.find('b');//Returns the position where the character 'b' first appears in a string, and returns 1 str.find('b', 2);//Returns the position where the character 'b' first appears in a string starting from position 2, and returns 4 str.find("bc");//As above, return the position where the string first appears, and return 1 str.find("bc", 2);//Return 4 str.rfind('b');//Reverse search, the principle is the same as above, and 4 is returned str.rfind('b', 3);//Return 1 str.rfind("bc");//Return 4 str.rfind("bc", 3);//Return 1 str[0];//Accessing characters in a string with Subscripts cout << (str == str) << endl;//string compares sizes in dictionary order
- Usage of erase() and remove() functions of string
//Use of erase() and remove() in string string str1, str2, str3, str4, str5; str1 = str2 = str3 = str4 = str5 = "I love AcWing! It's very funny!"; str1.erase(15);//Delete all elements of [15,end()), "I love AcWing!" str2.erase(6, 11);//Starting from the sixth element (including), delete the next 11 elements, "I love's very funny!" str3.erase(str3.begin() + 2);//Delete the element referred to by the iterator, "I ove AcWing! It's very funny!" str4.erase(str4.begin() + 7, str4.end() - 11);//Delete all elements of [str4.begin()+7,str4.end()-11), "I love very happy!" str5.erase(remove(str5.begin(), str5.end(), 'n'), str5.end());//Delete all characters' n 'in [str5.begin(),str5.end()), "I love AcWig! It's very fuy!"
④ Queue: also known as queue, it is a First In First Out (FIFO) data structure. It is defined in the < queue > header file. The queue container allows adding elements (in the queue) from one end (called the tail of the queue) and removing elements (out of the queue) from the other end (called the head of the queue).
⑤ Priority_queue: also known as priority queue, which is also defined in the < queue > header file. The difference from queue is that we can customize the priority of the data in it. The high priority queue is in front of the queue and out of the queue first. Priority_queue has all the characteristics of queue, including basic operations. On this basis, it only adds an internal sort. Its essence is heap implementation Now, it can be divided into small root heap and large root heap. The smaller elements in the small root heap are in the front, and the larger elements in the large root heap are in the front. Note: when creating priority_queue, the default is large root heap!
- How queue is defined
queue<int> que;//Define a queue where the element type is int queue<int> que[N];//Define a queue array with N queues priority_queue<int> smallHeap;//Define a small root heap priority_queue<int, vector<int>, greater<int> > bigHeap;//Define a large root heap
- Common built-in functions of queue
//Common built-in functions in queue queue<int> que; que.push(x);//Insert the element x at the end of the queue que.pop();//Queue header element of out of queue que.front();//Returns the queue header element of the queue que.back();//Returns the end of queue element of the queue que.size();//Returns the number of elements in the stack que.empty();//Returns whether the stack is empty. If it is empty, it returns true. Otherwise, it returns false
⑥ Deque: also known as double ended queue. Defined in the < deque > header file, vector container is a continuous memory space with one-way opening, and deque is a continuous linear space with two-way opening. The so-called two-way opening means that elements can be inserted and deleted at both ends of the head and tail respectively. Of course, vector can also insert elements at both ends of the head and tail, but insert them at its head The operation efficiency is extremely poor and cannot be accepted. The biggest difference between deque and vector is that deque allows the insertion and deletion of elements in the header using constant term time. The second is that deque has no concept of capacity, because it is a dynamic combination of piecewise continuous spaces, and a new space can be added and linked at any time.
- How deque is defined
deque<int> deq;//Define a deque where the element is of type int deque<int> deq[N];//Define a deque array with N deques deque<int> deq(len);//Define a deque with length len deque<int> deq(len, x);//Define a deque with length len and initialize each element as x deque<int> deq2(deq1);//Assign a value to v2 with deq1, and the type of deq2 is deque deque<int> deq2(deq1.begin(), deq1.begin() + 3);//Assign the third element 0 ~ 2 in deq1 to deq2
- Common built-in functions of deque
//Common built-in functions in deque deque<int> deq = { 1, 2, 3 };//Initialize vector, v:{1, 2, 3} deque<int>::iterator it = deq.begin();//Defines the iterator of the vector, pointing to begin() deq.push_back(4);//Insert element 4, V at the end of deque: {1, 2, 3, 4} deq.pop_back();//Delete the tail element of deque, v:{1, 2, 3} deq.push_front(4);//Insert element 4 in the head of deque, v:{4, 1, 2, 3} deq.pop_front();//Delete the header element of deque, v:{1, 2, 3} deq.size();//Returns the number of elements in the vector deq.empty();//Returns whether the vector is empty. If it is empty, it returns true. Otherwise, it returns false deq.front();//Returns the first element in the vector deq.back();//Returns the last element in the vector deq.begin();//Returns the iterator of the first element of the vector deq.end();//Returns the iterator at the position after the last element of the vector deq.clear();//Empty vector deq.erase(deq.begin());//Delete the element pointed to by the iterator it deq.insert(deq.begin(), 1);//Insert element 1 before the position pointed to by iterator it //Traversal by subscript for (int i = 0; i < deq.size(); i++) cout << deq[i] << ' '; //Traversal using iterators for (deque<int>::iterator it = deq.begin(); it != deq.end(); it++) cout << *it << ' '; //for_each traversal (C++11) for (auto x : deq) cout << x << ' ';
⑦ map/multimap: also known as mapping, which is defined in the < Map > header file. The underlying implementation mechanism of map and multimap is a red black tree. The function of map is to map any type of element to another element of any type, and all elements will be automatically sorted according to the key value of the element. All elements of map are pairs, with real values and key values at the same time. The first element of pair It is regarded as a key value, and the second element is regarded as a real value. Map does not allow two elements to have the same key value. The operation of multimap is similar to that of map, except that the key value of multimap can be repeated.
- How map/multimap is defined
map<string, int> mp;//Define a map that maps a string to an int map<string, int> mp[N];//Define a map array with N maps multimap<string, int> mulmp;//Define a multimap that maps a string to an int multimap<string, int> mulmp[N];//Define a multimap array with N multimaps
- Common built-in functions of map/multimap
//Common built-in functions in map/multimap map<string, int> mp; mp["abc"] = 3;//Map "abc" to 3 mp["ab"]++;//The integer to which "ab" is mapped++ mp.insert(make_pair("cd", 2));//Insert element mp.insert({ "ef", 5 });//ditto mp.size();//Returns the number of elements in the map mp.empty();//Returns whether the map is empty. If it is empty, it returns true. Otherwise, it returns false //mp.clear(); / / empty map mp.erase("ef");//Clear element {"ef", 5} mp["abc"];//Returns the value of the "abc" mapping mp.begin();//Returns the iterator for the first element of the map mp.end();//Returns the iterator at the position after the last element of the map mp.lower_bound("abc");//Returns the iterator of the first element whose key value is greater than or equal to "abc", {"abc", 3} mp.upper_bound("abc");//Returns the iterator of the first element whose key value is greater than "abc", {"cd", 2} //Traversal using iterators for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++) cout << (*it).first << ' ' << (*it).second << endl; //for_each traversal (C++11) for (auto x : mp) cout << x.first << ' ' << x.second << endl; //for_each traversal of extended inference range (C++17) for (auto &[k, v] : mp) cout << k << ' ' << v << endl;
⑧ set/multiset: also known as set, defined in the < set > header file. The feature of set is that all elements are automatically sorted according to the key value of the element. Unlike map, the elements of set can have real values and key values at the same time. The elements of set are both key values and real values. Set does not allow two elements to have the same key value. Therefore, in summary, the elements in set are orderly and not repeated.mu The characteristics and usage of ltiset are exactly the same as that of set. The only difference is that multiset allows repeated elements. The underlying implementation of set and multiset is a red black tree.
- Definition of set/multiset
set<int> st;//Define a set in which the element type is int set<int> st[N];//Define a set array with N sets multiset<int> mulst;//Define a multiset multiset<int> mulst[N];//Define a multiset array with N multisets
- Common built-in functions of set/multiset
//Common built-in functions in set/multiset set<int> st; st.insert(5);//Insert element 5 st.insert(6);//ditto st.insert(7);//ditto st.size();//Returns the number of elements in a set st.empty();//Returns whether set is empty. If it is empty, it returns true. Otherwise, it returns false st.erase(6);//Clear element 6 st.begin();//Returns the iterator of the first element of set st.end();//Returns the iterator at the position after the last element of the set st.clear();//Clear set st.lower_bound(5);//Returns the iterator of the first element whose key value is greater than or equal to 5, and returns the iterator of element 5 st.upper_bound(5);//Returns the iterator of the first element whose key value is greater than 5 and the iterator of element 7 //Traversal using iterators for (set<int>::iterator it = st.begin(); it != st.end(); it++) cout << (*it) << ' '; //for_each traversal (C++11) for (auto x : st) cout << x << ' ';
⑨unordered_map/unordered_set: respectively defined in < unordered_ Map > and < unordered_ In the set > header file, the hash table structure is used internally, which has the function of fast retrieval. Compared with map/set, the biggest difference is unordered_ map/unordered_ The elements in set are out of order. The time complexity of adding, deleting, and modifying queries is O (1) (the time complexity of adding, deleting, and modifying queries in map/set is O(logn)), but lower is not supported_ bound()/upper_ The bound() function.
- unordered_ map/unordered_ How set is defined
unordered_set<int> st;//Define an unordered_set, where the element type is int unordered_set<int> st[N];//Define an unordered_set array with N unordered_set unordered_map<int, int> mp;//Define an unordered_map unordered_map<int, int> mp[N];//Define an unordered_map array with N unordered_map
- unordered_ map/unordered_ Common built-in functions of set
//unordered_ map/unordered_ Common built-in functions in set unordered_set<int> st; unordered_map<int, int> mp; st.insert(5);//Insert element 5 st.insert(6);//ditto st.insert(7);//ditto st.size();//Return unordered_ Number of elements in set st.empty();//Return unordered_ Whether set is empty. If it is empty, return true; otherwise, return false st.erase(6);//Clear element 6 st.begin();//Return unordered_set the iterator of the first element st.end();//Return unordered_ Sets the iterator at the position after the last element st.clear();//Empty unordered_set mp.insert(make_pair(1, 2));//Insert element {1, 2} mp.insert({ 3, 4 });//ditto mp.size();//Return unordered_ Number of elements in map mp.empty();//Return unordered_ Whether the map is empty. If it is empty, return true; otherwise, return false mp.erase(3);//Clear element {3, 4} mp.begin();//Return unordered_ Iterator for the first element of the map mp.end();//Return unordered_ An iterator at a position after the last element of the map mp.clear();//Empty unordered_map //Traversal using iterators for (unordered_set<int>::iterator it = st.begin(); it != st.end(); it++) cout << (*it) << ' '; //for_each traversal (C++11) for (auto x : st) cout << x << ' '; //Traversal using iterators for (unordered_map<int, int>::iterator it = mp.begin(); it != mp.end(); it++) cout << (*it).first << ' ' << (*it).second << endl; //for_each traversal (C++11) for (auto x : mp) cout << x.first << ' ' << x.second << endl; //For extending inference range_ Each traversal (C++17) for (auto &[k, v] : mp) cout << k << ' ' << v << endl;
4, Detailed explanation of STL algorithm
The C + + standard library defines a set of generic algorithms. The reason why they are called generics is that they can operate on a variety of containers. They can not only act on standard library types, but also on built-in array types and even sequences of other types. Generic algorithms are defined in the < algorithm > header file, and the standard library also defines a set of generalized numeric algorithms, which are defined in the < numeric > header file.