The STL part of C + + of Jia Chengyang's rotten diary

Posted by ptraffick on Fri, 28 Jan 2022 02:24:24 +0100

Creative background:

The author studied a series of courses on program design and algorithm from Professor Guo Wei of Peking University at home in the winter vacation. In order to consolidate the learning results and prepare for the Blue Bridge Cup, the author recorded this series of learning notes on CSDN.

Write before:

The STL part of C + + is an efficient program library, including six components: container, iterator, algorithm, imitation function, iteration adapter and spatial configurator. In this paper, the author will only introduce some important knowledge points explained by the teacher in the course of programming and algorithm, and will not focus on other parts.

1, STL sorting algorithm sort

1. Three parameters of sort function:

(1) Start address of sort array

(2) End address of sort array

(3) Sorting method (sort can be sorted from large to small, or from small to large. It can even expand and define its own sorting method. If the third parameter does not specify, it is sorted from small to large by default)

Template: sort (start, end, sorting method)

2. Basic functions of sort

(1) Sort from small to large

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
	int arr[10] = { 12,32,43,45,67,7,1,78,14,4 };    //Define an array of size 10, completely out of order
	sort(arr, arr + 10);                             //Sort from small to large using sort
	for (int i = 0; i < 10; i++)                     
		cout << arr[i]<<' ';                         
	cout << endl;
	return 0;
}

//At this time, the output results are in good order. Arr [10] = {1,4,7,12,14,32,43,45,67,78};

(2) Sort from large to small

Without indicating the third parameter, sort is sorted from small to large by default. To achieve from large to small, just add the third parameter greater < data type > ().

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
	int arr[10] = { 12,32,43,45,67,7,1,78,14,4 };    //Define an array of size 10, completely out of order
	sort(arr, arr + 10, greater<int>());             //Use sort and add the third parameter greater < int > () to sort from large to small
	for (int i = 0; i < 10; i++)                     
		cout << arr[i]<<' ';                         
	cout << endl;
	return 0;
}

//At this time, the output result is a arranged array from large to small. Arr [10] = {78,67,45,43,32,14,12,7,4,1};

(3) Use the rules defined by yourself to sort the array

Sort can not only sort simply as above, but also sort more functions. The key lies in the third parameter cmp. Design the functions you want to achieve in cmp and add them to sort.

a. Design sorting from large to small in cmp

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>

using namespace std;

bool cmp(int a, int b) //int is the data type
{
	return a > b;     //Descending order, simple and rough
}

int main()
{
	int arr[10] = { 12,32,43,45,67,7,1,78,14,4 };    //Define an array of size 10, completely out of order
	sort(arr, arr + 10, cmp);                        //Use sort and add the third parameter cmp defined by ourselves to sort from large to small
	for (int i = 0; i < 10; i++)                     
		cout << arr[i]<<' ';                         
	cout << endl;
	return 0;
}

//At this time, the output result is a arranged array from large to small. Arr [10] = {78,67,45,43,32,14,12,7,4,1};

b. sort the size of single digits from small to large in cmp

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>

using namespace std;

bool cmp(int a, int b) //int is the data type
{
	return a % 10 < b % 10;     //Calculate the single digit size of the target number and arrange it in ascending order
}

int main()
{
	int arr[10] = { 19,32,43,47,67,96,1,78,14,55 };    //Define an array of size 10, completely out of order
	sort(arr, arr + 10, cmp);                        //Use sort and add the third parameter cmp defined by ourselves to sort the single digit size from small to large
	for (int i = 0; i < 10; i++)                     
		cout << arr[i]<<' ';                         
	cout << endl;
	return 0;
}

//At this time, the output result is a arranged array from large to small. Arr [10] = {1,32,43,14,55,96,47,67,78,19};

c. Sorting structures in cmp

For example: read in the names, student numbers and grades of {n (> 0) students, and output their personal information in the order of grades from large to small

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
struct student                                //Define the structure, which includes student name, student number and score
{
	char name[20];
	char id[20];
	int score;
};
bool com(student a, student b)
{
	return a.score > b.score;                 //Define the parameter com, and sort by the score from the largest to the smallest
}
int main()
{
	int n;
	cin >> n;
	struct student stu[1000];
	for (int i = 0; i < n; i++)
	{
		cin >> stu[i].name >> stu[i].id >> stu[i].score;
	}
	sort(stu, stu + n, com);                   //Sort the structure using the sort function
	for (int i = 0; i < n; i++)
	{
		cout << stu[i].name << ' ' << stu[i].id << ' ' << stu[i].score << endl;
	}
	return 0;
}

Input sample:

3
Joe Math990112 89
Mike CS991301 100
Mary EE990830 95

Output example:

Mike CS991301 100
Mary EE990830 95
Joe Math990112 89

Summary: sort is not a simple quick sort. It optimizes the ordinary quick sort. In addition, it also combines insert sort and push sort. The system will automatically select the appropriate sorting method according to your data form and data volume. This does not mean that it only selects one method for each sorting. It selects different methods in different situations in a complete sorting, such as sorting an array with a large amount of data, starting with quick sorting and piecewise recursion, After segmentation, when the data volume of each segment reaches a small value, it will not continue to recurse downward, but choose to insert sorting. If the recursion is too deep, it will choose push sorting. Its time complexity is n*log2n, which is much faster than bubble sorting and selective sorting.

2, STL binary search algorithm

1,binary_ Three parameters of search

(1) Start position of target array

(2) End position of target array

(3) Target value to find

Template: binary_search(start,end, target value)

Note: the search range is [n1, n2], n2 is not in the search range.

Find the element equal to the target value in this interval, and return true(1) if found, and false(0) if not found.

Meaning of equal: a = B < = > neither a < B nor B < a holds

binary_ The search order of search must be the same as that of the array, otherwise the found value is meaningless.

2,binary_ Basic functions and usage of search

Finds the target element in an ordered array

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	int arr[10] = { 4,3,6,9,2,8,1,7,5,10 };
    sort(arr,arr+10);
	cout << binary_search(arr, arr + 10, 8) << endl;    //Find 8 this target value in array arr
	cout << binary_search(arr, arr + 10, 0) << endl;    //Find the target value of 0 in the array arr
	return 0;
}
//The first group returns 1 and the second group returns 2

Meanwhile, binary_search can also find the target element in the customized sorting method. The template is binary_search(a,a+n, target value, collation structure name ())

 3,lower_ Basic functions and usage of bound

(1) find the target element in the ordered array and return a pointer, * p is the element with the smallest subscript in the search interval and greater than or equal to the target value. If not found, point to the element with subscript n2.

Template: * lower_ bound(a+n1,a+n2, target value)

                    lower_ bound(a+n1,a+n2, target value) - array name

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	int arr[10] = { 4,3,6,9,2,8,1,7,5,10 };
	sort(arr, arr + 10);
	cout << *lower_bound(arr, arr + 10, 8) << endl;       //Find the first element greater than or equal to 8 in the array arr
	cout << lower_bound(arr, arr + 10, 8) - arr << endl;  //Find the position of the first element greater than or equal to 8 in the array arr
	cout << *lower_bound(arr, arr + 10, 11) << endl;      //Find the first element greater than or equal to 11 in the array arr
	return 0;
}
//The pointer returns the first value greater than or equal to 8 in the target array, that is, 8, whose position is 7
//The pointer returns the position of n2, which is out of bounds

Meanwhile, lower_binary can also find the target element in the customized sorting method. The template is lower_binary(a,a+n, target value, collation structure name ())

4,upper_ Basic functions and usage of bound

(1) find the target element in the ordered array and return a pointer, * p is the element with the smallest subscript in the search interval and greater than the target value. If not found, point to the element with subscript n2.

Template: * upper_ bound(a+n1,a+n2, target value)

                    upper_ bound(a+n1,a+n2, target value) - array name

#include<cstdio>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

int main()
{
	int arr[10] = { 4,3,6,9,2,8,1,7,5,10 };
	sort(arr, arr + 10);
	cout << *upper_bound(arr, arr + 10, 8) << endl;       //Find the first element greater than 8 in array arr
	cout << upper_bound(arr, arr + 10, 8) - arr << endl;  //Find the position of the first element greater than 8 in the array arr
	cout << *upper_bound(arr, arr + 10, 11) << endl;      //Find the first element greater than 11 in array arr
	return 0;
}
//The pointer returns the first value greater than or equal to 8 in the target array, i.e. 9, whose position is 8
//The pointer returns the position of n2, which is out of bounds

Meanwhile, upper_ bound can also find the target element in the customized sorting method. The template is upper_ bound(a,a+n, target value, collation structure name ())

3, Balanced binary tree structure in STL: multiset and set and multimap and map

When you need to add and delete a large amount of data, you also need to find the data. At this time, sort + binary search is not feasible. You need to use the balanced binary tree structure to store the data.

multiset usage:

Define a variable of multiset type: multiset < type > arr; In this way, a multiset variable arr is defined, which can store type data. At the beginning, the ARR is empty.

Next, let's show the simple operation of multiset and some functions

Member methodfunction
c.begin()Returns a two-way iterator that points to the first (note, the first ordered) element in the container. If the multiset container is qualified with const, the method returns a bidirectional iterator of type const.
c.end()Returns a two-way iterator that points to the location after the last element of the container (note that it is the last one in order), usually used in conjunction with begin(). If the multiset container is qualified with const, the method returns a bidirectional iterator of type const.
find(val)Find the element with value val in the multiset container. If it is found successfully, return the bidirectional iterator pointing to the element; Otherwise, the same iterator as the end() method is returned. In addition, if the multiset container is qualified with const, the method returns a bidirectional iterator of const type.
lower_bound(val)Returns a bidirectional iterator pointing to the first element greater than or equal to val in the current multiset container. If the multiset container is qualified with const, the method returns a bidirectional iterator of type const.
upper_bound(val)Returns an iterator pointing to the first element greater than val in the current multiset container. If the multiset container is qualified with const, the method returns a bidirectional iterator of type const.
equal_range(val)This method returns a pair object (including 2 bidirectional iterators), where pair First and lower_ The return value of the bound () method is equivalent, pair Second and upper_ The return value of the bound () method is equivalent. That is, the method will return a range that contains all elements with a value of val.
empty()If the container is empty, return true; Otherwise, false.
size()Returns the number of elements in the current multiset container.
max_size()Returns the maximum number of elements that the multiset container can hold. Different operating systems have different return values.
insert()Inserts an element into the multiset container.
erase()Deletes the specified element stored in the multiset container.
swap()Swap all elements stored in 2 multiset containers. This means that the two multiset containers for the operation must be of the same type.
clear()Empty all elements in the multiset container, that is, make the size() of the multiset container 0.
emplace()Construct a new element directly at the specified position in the current multiset container. Its effect is the same as that of insert(), but it is more efficient.
emplace_hint()It is essentially the same way that empty () constructs a new element in a multiset container, except that the user must provide the method with an iterator indicating the generation location of the new element as the first parameter of the method.
count(val)In the current multiset container, find the number of elements with value val and return.
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#Include < set > / / this header file must be used when using multiset and set
using namespace std;

int main()
{
	multiset<int> h;                                 //Create a multiset variable h
	for (int i = 0; i < 10; i++)
	{
		int x;
		cin >> x;
		h.insert(x);                                 //Insert is an insert function, which inserts elements into h
	}
	for (auto j = h.begin(); j != h.end(); ++j)      //begin() returns the first element in the order, and end() returns the last element
	{
		cout << *j << ' ';
	}
	cout << endl;
	return 0;
}

Refer to the following for more usage of related functions
Original link: https://blog.csdn.net/sodacoco/article/details/84798621

set usage:

The difference between set and multiset is that there cannot be duplicate elements in set, so set may not succeed in inserting elements.

At the same time, most functions are also connected between the two, so I won't explain too much here, just mention the usage of iterators.

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#Include < set > / / this header file must be used when using multiset and set
using namespace std;

int main()
{
	set<int> h;                                 //Create a variable of type set h
	for (int i = 0; i < 10; i++)
	{
		int x;
		cin >> x;
		h.insert(x);                                 //Insert is an insert function, which inserts elements into h
	}
	set<int>::iterator j;                            //Create an iterator, and then use the iterator to operate
	for (j = h.begin(); j != h.end(); ++j)      //begin() returns the first element in the order, and end() returns the last element
	{
		cout << *j << ' ';
	}
	cout << endl;
	return 0;
}

For more information, please refer to this article

 [C++ STL] set usage details - fengMisaka - blog Garden (cnblogs.com)

The final multimap and map

Map and multimap are containers. There are four kinds of map containers, each of which is defined by a class template. All types of map containers hold elements of key value pairs. The element of the map container is an object of type pair < const K, t >, which encapsulates an object of type T and a key of type K associated with it. But here, we only learn two kinds, namely multimap and map.  

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#Include < Map > / / this header file is required to use map and multimap                     
using namespace std;

int main()
{
    multimap<char, int> h;                             //General method of defining a muitimap container
    for (int i = 0; i < 10; i++)
    {
        char y;                                        //Type of key value
        int x;                                         //Type of object saved
        cin >> y >> x;
        h.insert(pair<char, int>(y, x));               //read in data
    }
    for (auto j = h.begin(); j != h.end(); ++j)
    {
        cout << j->first << ' ' << j->second << endl;  //The method of outputting the data in the container. first is the data corresponding to the key value, and second is the data saved by the key value
    }

	return 0;
}

Member methodfunction
begin()Returns a two-way iterator that points to the first (note, the first ordered) key value pair in the container. If the multimap container is qualified with const, the method returns a bidirectional iterator of type const.
end()Returns a two-way iterator that points to the location after the last element of the container (note that it is the last one in order), usually used in conjunction with begin(). If the multimap container is qualified with const, the method returns a bidirectional iterator of type const.
rbegin()Returns a reverse bidirectional iterator pointing to the last (note, the last ordered) element. If the multimap container is qualified with const, the method returns a reverse bidirectional iterator of type const.
rend()Returns a reverse bidirectional iterator that points to the previous position of the first (note, the first ordered) element. If the multimap container is qualified with const, the method returns a reverse bidirectional iterator of type const.
cbegin()The function is the same as that of begin(), but the const attribute is added on the basis of it, which cannot be used to modify the key value pairs stored in the container.
cend()The function is the same as that of end(), but the const attribute is added on the basis of it, which cannot be used to modify the key value pairs stored in the container.
crbegin()It has the same function as rbegin(), but on the basis of it, const attribute is added, which can not be used to modify the key value pairs stored in the container.
crend()The function is the same as that of rend(), but the const attribute is added on the basis of it, which cannot be used to modify the key value pairs stored in the container.
find(key)Find the key value pair whose first key is key in the multimap container. If it is found successfully, return the bidirectional iterator pointing to the key value pair; Otherwise, the same iterator as the end() method is returned. In addition, if the multimap container is qualified with const, the method returns a bidirectional iterator of const type.
lower_bound(key)Returns a bidirectional iterator pointing to the first key value pair greater than or equal to key in the current multimap container. If the multimap container is qualified with const, the method returns a bidirectional iterator of type const.
upper_bound(key)Returns an iterator pointing to the first key value pair greater than key in the current multimap container. If the multimap container is qualified with const, the method returns a bidirectional iterator of type const.
equal_range(key)This method returns a pair object (including 2 bidirectional iterators), where pair First and lower_ The return value of the bound () method is equivalent, pair Second and upper_ The return value of the bound () method is equivalent. That is, the method will return a range containing key value pairs with key.
empty() If the container is empty, return true; Otherwise, false.
size()Returns the number of key value pairs stored in the current multimap} container.
max_size()Returns the maximum number of key value pairs that the multimap container can hold. The return values are different for different operating systems.
insert()Insert key value pairs into the multimap container.
erase()Delete the specified location, key value or key value pair in the specified area of the multimap container.
swap()Exchange the key value pairs stored in the two multimap containers, which means that the two key value pairs of the operation must be of the same type.
clear()Empty all key value pairs in the multimap container so that the size() of the multimap container is 0.
emplace()Constructs a new key value pair at the specified location in the current multimap container. Its effect is the same as inserting key value pairs, but it is more efficient.
emplace_hint()In essence, the method is the same as empty() to construct a new key value pair in the multimap container, except that the user must provide the method with an iterator indicating the generation position of the key value pair as the first parameter of the method.
count(key)In the current multimap container, find the number of key value pairs with key and return.

The basic usage and common functions of multimap and map are given above. Similarly, there can be no duplicate elements in map, but there can be in multimap. For more information, please refer to the following article.
https://blog.csdn.net/qq_28584889/article/details/83855734

Next, we will deepen the usage of map and set through an example.

Word frequency statistics: input a large number of words, each no more than 20 characters. Output these words in the order of occurrence from large to small. If the occurrence times are the same, output them in the order of dictionary order.

Input example: this is ok this plus that is plus plus

Output example: plus 3 # is 2 # this 2 # ok 1 # that 1

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>   
using namespace std;

struct Word{                                                     //Define Word type data
	int times;
	string wd;
};

struct Rule {
	bool operator()(const Word & w1, const Word & w2)const       //Defines the collation of a set
	{
		if (w1.times != w2.times)
		{
			return w1.times > w2.times;                          //When the occurrence times are different, sort by the occurrence times
		}
		else
		{
			return w1.wd < w2.wd;                                //When the number of occurrences is the same, it is sorted by the initial size
		}
	}
};

int main()
{
	string s;                                                    
	set<Word, Rule> st;
	map<string, int> mp;
	while (cin >> s)
	{
		++mp[s];
	}                                        
	for (map<string, int>::iterator i = mp.begin(); i != mp.end(); ++i)  //Define iterators
	{
		Word tmp;
		tmp.wd = i->first;                            
		tmp.times = i->second;
		st.insert(tmp);                              //Define tmp to bring all the data in the map into the set for the next sorting
	}
	for (set<Word, Rule>::iterator i = st.begin(); i != st.end(); ++i)
	{
		cout << i->wd << " " << i->times << endl;         //Finally, the ordered data is output through the iterator of set
	}

	return 0;
}

This question better summarizes the comprehensive usage of map and set. By doing this question, we can summarize and sort out the relationship and usage of the two. Map and set are really difficult knowledge points, but they are very practical.

Conclusion:

So far, the notes on the knowledge points of the STL part of c + + are over. It's 10000 words long. It's so long. I've never written such a long article before. The bad diary series is the name of the podcast I wrote for the algorithm article. This is the first article in the series. Affected by the winter vacation and the new year (actually I want to play), it is expected to post another note every two or three days. The whole series is expected to be about 60000 words (shaking my hand when typing 60000).

Topics: C++