Detailed explanation of C++ STL (recommended collection!!!)

Keywords: C++ Algorithm STL

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.

Posted by reethu on Tue, 05 Oct 2021 14:44:40 -0700