[20000 words play STL ~ take it away quickly] Chapter 0 of Blue Bridge Cup algorithm competition series - Blue Bridge compulsory test point and standard template library STL

Posted by mdnghtblue on Sun, 21 Nov 2021 06:15:38 +0100

Welcome back to: meet blue bridge, meet you, not negative code, not negative Qing!

catalogue

[supplement]: common header files and library functions

1.#include

sscanf() and sprintf()

2.#include

3.#include

4.#include

(1).fabs(double x)

(2).pow(double r, double p)

(3).sqrt(double x)

5.#include

(1).strlen()

(2).strcmp()

(3).strcpy()

(4).strcat()

6.#include 

7.#include

8.#include

9.#include

1, Detailed explanation of common usage of string

1. Definition of string

2. Access to content in string

(1) . access by subscript

(3) . access through iterators

3. Analysis of common function examples of string

(1).operator+=

(2).compare operator

(3).length() / size()

(4).insert()

(5).erase()

(6).clear()

(7).substr()

(8).string::npos

(9).find()

(10).replace()

2, Detailed explanation of common usage of queue

1. Definition of queue

2. Access to elements in the queue container

3. Analysis of common function examples of queue

(1).push()

(2).front(), back()

(3).pop()

(4).empty()

(5).size()

3, Detailed explanation of the common usage of stack

1. Definition of stack

2. Access to elements in stack container

3. Analysis of common stack function examples

(1).push()

(2).top()

(3).pop()

(4).empty()

(5).size()

4, Common functions under the algorithm header file

1.max(), min() and abs()

2.swap()

3.reverse()

4.next_permutation()

5.fill()

6.sort()

<1> . sorting of basic data type array

<2> . sorting of structure array

<3> . sorting of containers

7.lower_bound() and upper_bound()

5, Blue bridge conclusion: meet blue bridge meet you, not negative code, not negative Qing!

[preface]

This is a follow-up to the last article. Iron juice can review the content of the previous article first.

Chapter 0 of Blue Bridge Cup algorithm competition series - Blue Bridge compulsory test site and standard template library STL (I) (10000 word blog, it is recommended to take it away)_ Safe blog - CSDN blog

Last time, several iron juice suggested that I change more pictures, indicating that I'm tired of reading them. Many enthusiastic little friends privately sent me some, but not many can be used because of the format and size. However, I still want to thank you here. Hug.

[supplement]: common header files and library functions

  • #include<stdio.h>
  • #include<stdlib.h>
  • #include<time.h>
  • #include<math.h>
  • #include<string.h>
  • #include<vector>
  • #include<string>
  • #include<queue>
  • #include<stack>
  • #include<algorithm>

1.#include<stdio.h>

  • scanf()
  • printf()
  • getchar()
  • putchar()
  • gets()
  • puts()
  • sscanf()
  • sprintf()

Standard input / output header files. Of course, in addition to scanf () and printf(), sscanf() and sprintf() are also very important. The teacher has never talked about these two library functions, but they often appear when looking at the problem solution. They are sharp tools for processing strings. We'll talk about them later. Let's talk about the disadvantages of scanf(). For scanf() function, you can't read in spaces. It ends when you encounter spaces, so it's very inconvenient to deal with strings. Therefore, there are two library functions to process strings: gets() and puts(), which are used to input a line of string, identify the end of '\ n', and will not end in case of spaces. Puts() is used to output a line of string, followed by a newline. putchar() and getchar() are not used much. If you are interested, you can learn about them by yourself.

sscanf() and sprintf()

sscanf() and sprintf() are sharp tools to deal with string problems. It is necessary for us to learn them (sscanf() can be understood as string + scanf, sprintf can be understood as string + printf, both under the stdio.h header file). Let's review scanf() and printf(). If you want to input int variable n from the screen and output int variable n to the screen, you can write it as follows:

scanf("%d", &n);
printf("%d", n);

In fact, the above expression can actually be expressed as the following, where screen represents the screen:

scanf(screen, "%d", &n);
printf(screen, "%d", n);

It can be found that the input of scanf() actually transfers the contents of screen to N in the format of "% d" (i.e. from left to right), while the output of printf() transfers n to screen in the format of "% d" (i.e. from right to left)

sscanf() and sprintf() are in the same format as above, except that screen is replaced with a character array (assuming a char array str[100]), as shown below:

sscanf(str, "%d", &n);
sprintf(str, "%d", n);

The above sscanf() method is used to write the contents of the character array str to n in the format of "% d" (or from left to right)

Examples are as follows:

#include<stdio.h>

int main()
{
	int n = 0;
	char str[100] = "123";
	sscanf(str, "%d", &n);

	printf("%d\n", n);//Output 123

	return 0;
}

sprintf() is used to write n to str character array in the format of "% d" (or from right to left)

Examples are as follows:

#include<stdio.h>

int main()
{
	int n = 233;
	char str[100];
	sprintf(str, "%d", n);
	printf("%s\n", str);//Output 233
	return 0;
}

The above are just some simple applications. In fact, you can use scanf() and printf() for complex format input and output. For example, the following code uses sscanf() to write the contents of the character array str in the format of "% d:%lf,%s" to int type variable n, double type variable db and char type array str2

#include<stdio.h>

int main()
{
	int n;
	double db;
	char str[100] = "2048:3.14,hello", str2[100];
	sscanf(str, "%d:%lf,%s", &n, &db, str2);
	printf("n = %d, db = %lf, str2 = %s\n", n, db, str2);
	return 0;
}

Similarly, the following code uses sprintf() to write int variable n, double variable db and char array str2 into character array str in the format of "% d:%lf,%s"

#include<stdio.h>

int main()
{
	int n = 12;
	double db = 3.1415;
	char str[100], str2[100] = "good";
	sprintf(str, "%d:%.2lf,%s", n, db, str2);
	printf("str = %s\n", str);
	return 0;
}

2.#include<stdlib.h>

It is mainly used for generating random numbers and dynamic memory development. The commonly used library functions are srand((unsigned int) time(NULL)),rand() and malloc() for dynamic memory development. It will be simpler to use new

3.#include<time.h>

When generating random numbers above, the time() function is commonly used to generate time stamps as random number seeds

4.#include<math.h>

  • fabs()
  • sqrt()
  • pow()
  • floor()
  • ceil()
  • round()

Using mathematical functions can save a lot of time, so be sure to remember that the commonly used ones are fabs(), sqrt(), and pow()

(1).fabs(double x)

This function is used to take the absolute value of a double variable.

(2).pow(double r, double p)

This function is used to return r ^ p. both r and p are required to be double

(3).sqrt(double x)

This function returns the arithmetic square root of a double variable

Here is a brief introduction to the three most commonly used.

5.#include<string.h>

  • strlen()
  • strcmp()
  • strcpy()
  • strcat()

(1).strlen()

strlen() function can get the number of characters before the first \ 0 in the character array

(2).strcmp()

The strcmp() function returns the comparison results of two string sizes. The comparison principle is in dictionary order. The so-called dictionary order is the order of strings in the dictionary. Therefore, if there are two character arrays str 1 and str 2, and str 1[0...k - 1] == str 2[0...k - 1], STR1 [k] < str2 [k], then the dictionary order of str 1 is less than str2. For example, the dictionary order of "a" is less than "b" and the dictionary order of "aaaa" is less than "aab"

Return value of strcmp() function:

  • If character array 1 < character array 2, a negative integer (not necessarily - 1, determined by the compiler) is returned
  • Returns 0 if character array 1 = = character array 2
  • If character array 1 >   If the character array is 2, a positive integer (not necessarily 1, determined by the compiler) is returned

(3).strcpy()

The strcpy() function can copy one string to another. The format is as follows:

strcpy(Character array 1, character array 2);

Note: copy character array 2 to character array 1. The "copy" here includes the end flag \ 0   

Examples are as follows:

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[50] = "Thank";
	char str2[50] = "you for your smile.";
	strcpy(str1, str2);
	puts(str1);//Output you for your smile
	//printf("%s\n", str1);
	return 0;

}

(4).strcat()

strcat() can splice one string after another

strcat(Character array 1, character array 2);

Note that the character array 2 is spliced after the character array 1  

Examples are as follows:

#include<stdio.h>
#include<string.h>

int main()
{
	char str1[50] = "Thank";
	char str2[50] = "you for your smile.";
	strcat(str1, str2);
	puts(str1);//Output thank you for your smile
	//printf("%s\n", str1);
	return 0;
	return 0;
}

6.#include<vector> 

Common functions:

  • push_back()
  • pop_back()
  • size()
  • clear()

7.#include<queue>

Common functions

  • push()
  • pop()
  • front()
  • back()
  • empty()
  • size()

8.#include<stack>

Common functions:

  • push()
  • pop()
  • top()
  • empty()
  • size()

9.#include<algorithm>

Common functions:

  • max()
  • min()
  • swap()
  • fill()
  • sort()

Here are some common containers:  

1, Detailed explanation of common usage of string

In C language, character array char str [] is generally used to store strings, but using character array sometimes seems troublesome, and it is easy to make errors due to lack of experience. In order to make it easier for programmers to operate strings, C + + adds string type to STL and encapsulates the common requirements and functions of strings, which makes the operation more convenient and not easy to make mistakes.

If you want to use string, you need to add a string header file, #include < string > (note that string.h and string are different header files). In addition, you need to add a sentence under the header file: "using namespace std;" so that you can use strings in your code. Let's look at some common uses of string.

1. Definition of string

The way to define a string is the same as the basic data type. You only need to follow the variable name after the string:

string str;

If you want to initialize, you can directly assign a value to a variable of type string:

string str = "abcd"

2. Access to content in string

(1) . access by subscript

Generally speaking, you can access string s directly like character arrays:

#include<stdio.h>
#include<string>
using namespace std;

int main()
{
	string str = "abcd";
	for (int i = 0; i < str.length(); i++)
	{
		printf("%c ", str[i]);//Output a b c d
	}
	return 0;
}

Note that if you want to read and output the entire string, you can only use cin and   cout:

#Include < iostream > / / CIN and cout are in the iostream header file, not stdio.h
#include<string>

using namespace std;
int main()
{
	string str;
	cin >> str;
	cout << str;

	return 0;
}

The above code will output the same string for any string input.

So, is there really no way to use printf to output string? In fact, there is, that is, c_str() converts string type to character array for output. An example is as follows:

#include<stdio.h>
#include<string>

using namespace std;

int main()
{
	string str = "abcd";
	printf("%s\n", str.c_str());//Use string str as c_str() becomes a character array
	return 0;
}

(3) . access through iterators

Generally, only (1) can meet the access requirements, but some functions such as insert() and erase() require iterators as parameters, so you still need to learn the usage of string iterators.

Since string does not require parameters like other STL containers, it can be directly defined as follows:

string::iterator it;

In this way, the iterator it is obtained, and each bit in the string can be accessed through * it:

#include<stdio.h>
#include<string>

using namespace std;

int main()
{
	string str = "abcd";
	for (string::iterator it = str.begin(); it != str.end(); it++)
	{
		printf("%c ", *it);//Output a b c d
	}
	return 0;
}

Finally, it is pointed out that string, like vector, supports the addition and subtraction of a number directly to the iterator, such as str.begin() + 3, which is feasible

3. Analysis of common function examples of string

  • operator+=
  • compare operator
  • length() / size()
  • insert()
  • erase()
  • clear()
  • substr()
  • string::nops
  • find()
  • replace()

(1).operator+=

This is the addition of strings. You can splice two strings directly

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str1 = "abc", str2 = "xyz", str3;
	str3 = str1 + str2;//Splice str1 and str2 and assign a value to str3
	str1 = str1 + str2;//Splice str2 directly to str1

	cout << str1 << endl;//Output abcxyz
	cout << str3 << endl;//Output abcxyz

	return 0;
}

(2).compare operator

Two string types can be used directly = =,! =, <, < =, >, >= Compare size. The comparison rule is dictionary order.

Examples are as follows:

#include<stdio.h>
#include<string>

using namespace std;

int main()
{
	string str1 = "aa", str2 = "aaa", str3 = "abc", str4 = "xyz";
	if (str1 < str2)//If the dictionary order of str1 is less than str2, output ok1
	{
		printf("ok1\n");//Output ok1
	}

	if (str1 != str3)//If the dictionary order of str1 and str3 is not equal, output ok2
	{
		printf("ok2\n");//Output ok2
	}

	if (str4 >= str3)//If str4 dictionary order is greater than or equal to str3, output ok3
	{
		printf("ok3\n");//Output ok3
	}
	return 0;
}

(3).length() / size()

length() returns the length of a string, that is, the number of characters stored. The time complexity is O(1). size() is basically the same as length ()

Examples are as follows:

string str = "abcdef";
printf("%d %d\n", str.length(), str.size());//Output 6

(4).insert()

There are many ways to write the insert() function of string. Here are some common ways to write it. Time complexity is O(N)

1.insert(pos, string). Insert a string at the pos number

Examples are as follows:

string str = "abcxyz", str2 = "opq";
str.insert(3, str2);//It is also possible to insert opq into str[3] and write str2 in parentheses directly as "opq"
cout<<str<<endl;//Output abcopqxyz

2. Insert (it, it2, it3). It is the position of the original string to be inserted. It2 and it3 are the beginning and end iterators of the string to be inserted, which is used to indicate that the string [it2, it3) will be inserted at the position of it

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "abcxyz", str2 = "opq";//str is the original string and str2 is the string to be inserted
	//Insert str2 in position 3 of str (i.e. between c and x)
	str.insert(str.begin() + 3, str2.begin(), str2.end());
	cout << str << endl;//Output abcopqxyz
	return 0;
}

(5).erase()

erase() has two uses: delete a single element and delete all elements in an interval. The time complexity is O(N)

1. Delete a single element: str.erase(it) is used to delete a single element. It is the iterator of the element to be deleted

Examples are as follows:

#include<iostream>
#include<stdio.h>

using namespace std;
int main()
{
	string str = "abcdefg";
	str.erase(str.begin() + 4);//Delete position 4 (i.e. E.)
	cout << str << endl;//Output abcdfg
	return 0;
}

2. Delete all elements in an interval: there are two methods:

  • str.erase(first, last), where first is the start iterator of the interval to be deleted, and last is the next address of the end iterator of the interval to be deleted, that is, delete [first, last)

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "abcdefg";
	//Delete the element in [str.begin() + 2, str.end() - 1), i.e. cdef
	str.erase(str.begin() + 2, str.end() - 1);
	cout << str << endl;//Output abg
	return 0;
}
  • str.erase(pos, length), where pos is the starting position to be deleted, and length is the number of characters to be deleted.

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "abcdefg";
	str.erase(3, 2);//Delete de
	cout << str << endl;//Output abcfg
	return 0;
}

(6).clear()

clear() can clear the data in the string, and the time complexity is generally O(1)

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "abcd";
	str.clear();//Empty string
	cout << str.length() << endl;//Output 0
	return 0;
}

(7).substr()

substr(pos, len) returns a substring of length len starting from pos, with a time complexity of O(len)

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "Thank you for your smile.";
	cout << str.substr(0, 5) << endl;//Output Thank
	cout << str.substr(14, 4) << endl;//Output your
	cout << str.substr(19, 5) << endl;//Output smile
	return 0;
}

(8).string::npos

string::npos is a constant with its own value of - 1. However, since it is of unsigned int type, it can also be considered as the maximum value of unsigned int type, which can be considered as 4294967295. string::npos is used as the return value when the find function is mismatched.

(9).find()

str.find(str): when str2 is a substring of STR, return the position where it first appears in str. if str2 is not a substring of STR, return string::npos

str.find(str2, pos) matches str2 from the pos number of str, and the return value is the same as above. The time complexity is O(M*N), and M and N are the lengths of str2 and str respectively

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "Thank you for your smile";
	string str2 = "you";
	string str3 = "me";
	if (str.find(str2) != string::npos)
	{
		cout << str.find(str2) << endl;//Output 6
	}
	if (str.find(str2, 7) != string::npos)
	{
		cout << str.find(str2, 7) << endl;//Output 14
	}
	if (str.find(str3) != string::npos)
	{
		cout << str.find(str3) << endl;
	}
	else
	{
		cout << "I know there is no position for me." << endl;
	}
	return 0;
}

(10).replace()

str.replace(pos,len,str2) replaces the substring of str with length len starting from pos with upper str2

str.replace(it1,it2,str2) replaces the substring of the iterator [it1, it2) range of str with str2

Examples are as follows:

#include<iostream>
#include<string>

using namespace std;

int main()
{
	string str = "Maybe you will turn around.";
	string str2 = "will not";
	string str3 = "surely";
	cout << str.replace(10, 4, str2) << endl;
	cout << str.replace(str.begin(), str.begin() + 5, str3) << endl;
	return 0;
}

2, Detailed explanation of common usage of queue

Queue is translated into queue. In STL, it is mainly to implement a first in first out container. When breadth first search needs to be implemented, you can use queue instead of manually implementing a queue to improve the accuracy of the program.

1. Definition of queue

To use queue, you need to add the header file #include < queue >, and add "using namespace std;" under the header file, and then you can use it.

Its definition is written in the same way as other STL containers. typename can be any basic data type and container:

queue<typename> name;

2. Access to elements in the queue container

Because the queue itself is a restricted data structure of first in first out, the first element of the queue can only be accessed through front() or the last element can only be accessed through back() in STL.

Examples are as follows:

#include<stdio.h>
#include<queue>

using namespace std;

int main()
{
	queue<int> q;
	for (int i = 1; i <= 5; i++)
	{
		q.push(i);//push(i) is used to push i into the queue, so queue 1 2 3 4 5 in turn 
	}
	printf("%d %d\n", q.front(), q.back());//The output is 1.5
	return 0;
}

3. Analysis of common function examples of queue

  • push()
  • front()
  • back()
  • pop()
  • empty()
  • size()

(1).push()

push(x) queue x with time complexity O(1)

(2).front(), back()

front(), back() can obtain the team head element and the team tail element respectively, and the time complexity is O(1)

Note: before using the front() and pop() functions, you must use empty() to determine whether the queue is empty. Otherwise, an error may occur because the queue is empty

(3).pop()

pop() causes the first element of the team to leave the team, and the time complexity is O(1)

Examples are as follows:

#include<stdio.h>
#include<queue>

using namespace std;

int main()
{
	queue<int> q;
	for (int i = 1; i <= 5; i++)
	{
		q.push(i);
	}
	for (int i = 0; i < 3; i++)
	{
		q.pop();//Queue elements 3 times, 1 2 3 times in turn
	}
	printf("%d\n", q.front());//Output 4
	return 0;
}

(4).empty()

empty() checks whether the queue is empty. If it returns true, it is empty. If it returns false, it is not empty. The time complexity is O(1)

Examples are as follows:

#include<stdio.h>
#include<queue>

using namespace std;

int main()
{
	queue<int> q;
	if (q.empty() == true)//At first, there were no elements in the queue, so it was empty
	{
		printf("Empty\n");
	}
	else
	{
		printf("Not Empty\n");
	}
	q.push(1);
	if (q.empty() == true)
	{
		printf("Empty\n");
	}
	else
	{
		printf("Not Empty\n");
	}
	return 0;
}

(5).size()

size() returns the number of elements in the queue. The time complexity is O(1)

Examples are as follows:

#include<stdio.h>
#include<queue>

using namespace std;

int main()
{
	queue<int> q;
	for (int i = 1; i <= 5; i++)
	{
		q.push(i);
	}
	printf("%d\n", q.size());//Output 5
	return 0;
}

[Extension]: there are also two kinds of containers in STL container related to queues: deque and priority_queue. The former is a queue that can be inserted and deleted from beginning to end, and the latter is a container that uses heap implementation to place the largest element of the current queue at the head of the queue. It will not be introduced here for the time being. It will be supplemented later if necessary.

3, Detailed explanation of the common usage of stack

Stack is a first in and last out container implemented in STL. Stack is used to simulate some recursion to prevent the program from running error due to the limitation of stack memory.

1. Definition of stack

To use stack, you should first add the header file #include < stack >, and add "using namespace std;" under the header file, and then you can use it.

Its definition is written in the same way as other STL containers. typename can be any basic data type or container:

stack<typename> name;

2. Access to elements in stack container

Because the stack itself is a first in and last out data structure, the top element of the stack can only be accessed through top() in the STL stack

Examples are as follows:

#include<stdio.h>
#include<stack>

using namespace std;

int main()
{
	stack<int> st;
	for (int i = 1; i <= 5; i++)
	{
		st.push(i);//Stack 1 2 3 4 5 in sequence
	}
	printf("%d\n", st.top());//Output 5
	return 0;
}

3. Analysis of common stack function examples

  • push()
  • top()
  • pop()
  • empty()
  • size()

(1).push()

push(x) puts x on the stack, and the time complexity is O(1),

(2).top()

top() obtains the top element of the stack, and the time complexity is O(1)

(3).pop()

pop() is used to pop up stack top elements. The time complexity is O(1)

Examples are as follows:

#include<stdio.h>
#include<stack>

using namespace std;

int main()
{
	stack<int> st;
	for (int i = 1; i <= 5; i++)
	{
		st.push(i);
	}
	for (int i = 0; i < 3; i++)
	{
		st.pop();
	}
	printf("%d\n", st.top());//Output 2
	return 0;
}

(4).empty()

empty() can detect whether the stack is empty, return true as empty, return false as non empty, and the time complexity is O(1)

(5).size()

size() returns the number of elements in the stack. The time complexity is O(1)

4, Common functions under the algorithm header file

To use the algorithm header file, you need to add a line "using namespace std;" under the header file to use it normally

  • max(),min(),abs()
  • swap()
  • reverse()
  • next_permutation()
  • fill()
  • sort()
  • lower_bound() and upper_bound()

1.max(), min() and abs()

max(x,y) and min(x,y) return the maximum and minimum values of X and Y respectively, and the parameters must be two, which can be floating-point numbers. If you want to return the maximum values of three numbers x, y and Z, you can use the writing method of max(x, max(y, z)); abs(x) returns the absolute value of X. Note: at this time, X must be an integer. For the absolute value of floating-point number, please use fabs under math header file

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int x = -1;
	int y = -2;
	printf("%d %d\n", max(x, y), min(x, y));//Output - 1 - 2
	printf("%d %d\n", abs(x), abs(y));//Output 1 2
	return 0;
}

2.swap()

swap(x, y) is used to exchange the values of X and y

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int x = 10;
	int y = 20;
	swap(x, y);
	printf("%d %d\n", x, y);//Output 20 10
	return 0;
}

3.reverse()

reverse(it, it2) can reverse the elements whose array pointer is between [it, it2) or the elements whose container iterator is within [it, it2)

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int arr[10] = { 10,11,12,13,14,15 };
	reverse(arr, arr + 4);//Invert arr[0]~arr[3]
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", arr[i]);//Output 13,12,11,10,14,15
	}

	return 0;
}

If you invert the elements in the container (such as string string), the result is the same

Examples are as follows:

#include<stdio.h>
#include<string>
#include<algorithm>

using namespace std;

int main()
{
	string str = "abcdefghi";
	reverse(str.begin() + 2, str.begin() + 6);//Reverse str[0]~str[5]
	for (int i = 0; i < str.length(); i++)
	{
		printf("%c", str[i]);//Output abfedcghi
	}
	return 0;
}

4.next_permutation()

next_permutation() gives the next sequence of a sequence in the full permutation

For example, when n == 3, the full arrangement is:

123

132

213

231

312

321

So the next sequence of 231 is 312

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int a[10] = { 1,2,3 };
	//The sequence between a[0]~a[2] needs to solve next_permutation
	do
	{
		printf("%d%d%d\n", a[0], a[1], a[2]);
	} while (next_permutation(a, a + 3));
	return 0;
}

In the above code, the reason for using the loop is that next_permutation will return false when it has reached the last of the full permutation, which will facilitate the exit of the loop. The reason for using the do...while statement instead of the while statement is that the sequence 1, 2, 3 itself also needs to be output. If you use while, you will directly jump to the next sequence and then output, so the result will be 123 less

5.fill()

fill() can assign an interval in an array or container to the same value. Unlike memset, the assignment here can be any value in the corresponding range of the array type

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int a[5] = { 1,2,3,4,5 };
	fill(a, a + 5, 133);//Assign a[0]~a[4] to 133
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", a[i]);//Output 133 133 133
	}
	return 0;
}

6.sort()

As the name suggests, sort() is a function for sorting. It uses different sorting methods according to specific situations, which is more efficient. Generally speaking, the qsort function in C language is not recommended because qsort is cumbersome and involves many pointer operations.

  • How do I use sort?

The header file "#include < algorithm >" and "using namespace std;" must be added to the use of sort function. Its use method is as follows:

Sort (first element address (required), next address of last element address (required), comparison function (not required));

You can see that there are three parameters of sort, of which the first two are required, and the comparison function can be filled in as needed. If the comparison function is not written, the interval given above will be sorted incrementally by default.

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int a[6] = { 9,4,2,5,6,-1 };
	//Sort a[0]~a[3] from small to large
	sort(a, a + 4);
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", a[i]);//Output 2 4 5 9 6 - 1
	}
	putchar('\n');
	//Sort a[0]~a[5] from small to large
	sort(a, a + 6);
	for (int i = 0; i < 6; i++)
	{
		printf("%d ", a[i]);//Output - 1 2 4 5 6 9
	}
	return 0;
}

[knocking on the blackboard]: special attention should be paid to understanding the next address of the tail element address!

Sort the double array:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	double a[] = { 1.4,-2.1,9 };
	sort(a, a + 3);
	for (int i = 0; i < 3; i++)
	{
		printf("%.1lf ", a[i]);
	}
	return 0;
}

Sort char array (dictionary order by default)

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	char c[] = { 'T', 'W','A', 'K' };
	sort(c, c + 4);
	for (int i = 0; i < 4; i++)
	{
		printf("%c", c[i]);//Output AKTW
	}
	return 0;
}

What we need to know is that if the sequence is sorted, the elements in the sequence must be comparable, so we need to formulate sorting rules to establish this comparability. Especially for structures, there is no size relationship, so we need to consider formulating comparison rules. The third optional parameter of sort is the cmp function, which is used to implement this rule.

  • How to implement the comparison function cmp

The following describes how to write cmp when sorting by user-defined rules for basic data types, structure types and STL containers.

<1> . sorting of basic data type array

If the comparison function is not filled in, it will be sorted from small to large by default.

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int a[] = { 3,1,4,2 };
	sort(a, a + 4);
	for (int i = 0; i < 4; i++)
	{
		printf("%d ", a[i]);//Output 1 2 3 4
	}
	return 0;
}

If you want to sort from large to small, you need to use the comparison function cmp to "tell" sort when to exchange elements (reverse the size comparison relationship of elements)

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

bool cmp(int a, int b)
{
	return a > b;//It can be understood that when a > b, put a in front of B
}

int main()
{
	int a[] = { 3,1,4,2 };
	sort(a, a + 4, cmp);
	for (int i = 0; i < 4; i++)
	{
		printf("%d ", a[i]);//Output 4 3 2 1
	}

	return 0;
}

In this way, the elements with large values can be placed in front, which meets the requirements of sorting from large to small.

Similarly, the code for sorting double arrays from large to small is as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

bool cmp(double a, double b)
{
	return a > b;//The same is a > B
}

int main()
{
	double a[] = { 1.4,-2.1,9 };
	sort(a, a + 3, cmp);
	for (int i = 0; i < 3; i++)
	{
		printf("%.1lf ", a[i]);//Output 9.0 1.4 - 2.1
	}
	return 0;
}

Sort char arrays from large to small as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

bool cmp(char a, char b)
{
	return a > b;//It can be understood that when a > b, put a before B
}

int main()
{
	char c[] = { 'T','W','A','K' };
	sort(c, c + 4, cmp);
	for (int i = 0; i < 4; i++)
	{
		printf("%c", c[i]);//Output WTKA
	}
	return 0;
}

[memory method]:

If you want to arrange the data from small to large, use '<' because "a < B" is small on the left and large on the right; if you want to arrange the data from large to small, use '>' because "a > b" is large on the left and small on the right. When you are not sure or forget, you might as well try both and you will know which one to use.

<2> . sorting of structure array

The following structures are now defined:

struct node{
    int x, y;
}ssd[10];

If you want to sort the ssd array from large to small by x (that is, one-level sorting), you can write the cmp function as follows:

bool cmp(node a, node b){
    return a.x > b.x;
}

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

struct node
{
	int x;
	int y;
}ssd[10];

bool cmp(node a, node b)
{
	return a.x > b.x;//Sort the structure array by x value from large to small
}

int main()
{
	ssd[0].x = 2;
	ssd[0].y = 2;
	ssd[1].x = 1;
	ssd[1].y = 3;
	ssd[2].x = 3;
	ssd[2].y = 1;
	sort(ssd, ssd + 3, cmp);
	for (int i = 0; i < 3; i++)
	{
		printf("%d %d\n", ssd[i].x, ssd[i].y);
	}
	return 0;
}

If you want to sort x from large to small first, but when x is equal, sort y from small to large (i.e. secondary sorting), the cmp is written as follows:

bool cmp(node a, node b)
{
    if(a.x != b.x)
    {
        return a.x > b.x;
    }
    else
    {
        return a.y < b.y;
    }
}

The cmp function here first determines whether the x elements in the structure are equal. If they are not equal, they are sorted directly according to the size of x; otherwise, they are sorted according to the size of y.

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

struct node
{
	int x;
	int y;
}ssd[10];

bool cmp(node a, node b)
{
	if (a.x != b.x)
	{
		return a.x > b.x;//When x is not equal, sort by X from large to small
	}
	else
	{
		return a.y < b.y;//When x is equal, sort by y from small to large
	}
}
int main()
{
	ssd[0].x = 2;
	ssd[0].y = 2;
	ssd[1].x = 1;
	ssd[1].y = 3;
	ssd[2].x = 3;
	ssd[2].y = 1;
	sort(ssd, ssd + 3, cmp);//sort

	for (int i = 0; i < 3; i++)
	{
		printf("%d %d\n", ssd[i].x, ssd[i].y);
	}
	return 0;
}

<3> . sorting of containers

In the STL standard container, only vector, string and deque can use sort. This is because containers such as set and map are implemented with red and black trees (you can understand them), and the elements themselves are orderly, so sort sorting is not allowed

An example of vector is as follows:

#include<stdio.h>
#include<vector>
#include<algorithm>

using namespace std;

bool cmp(int a, int b)//Because the element in the vector is of type int, it is still a comparison of int
{
	return a > b;
}


int main()
{
	vector<int> vi;
	vi.push_back(3);
	vi.push_back(1);
	vi.push_back(2);
	sort(vi.begin(), vi.end(), cmp);
	for (vector<int>::iterator it = vi.begin(); it != vi.end(); it++)
	{
		printf("%d ", *it);//Output 3 2 1
	}
	return 0;
}

Let's look at the sorting of string s. An example is as follows:

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

using namespace std;

int main()
{
	string str[3] = { "bbbb", "cc", "aaa" };
	sort(str, str + 3);//Output the string array from small to large according to the dictionary tree
	for (int i = 0; i < 3; i++)
	{
		cout << str[i] << endl;
	}

	return 0;
}

In the above example, if you need to sort by string length from small to large, you can write as follows:

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

using namespace std;

bool cmp(string str1, string str2)
{
	return str1.length() < str2.length();//Sort by the length of the string from small to large
}

int main()
{
	string str[3] = { "bbbb", "cc", "aaa" };
	sort(str, str + 3, cmp);
	for (int i = 0; i < 3; i++)
	{
		cout << str[i] << endl;
	}

	return 0;
}

7.lower_bound() and upper_bound()

lower_bound() and upper_bound() needs to be used in an ordered array or container

lower_bound(first, last, val) is used to find the position of the first val element with a value greater than or equal to val in the [first, last) range of an array or container. If it is an array, it returns the pointer to the position; if it is a container, it returns the iterator of the position.

upper_bound(first, last, val) is used to find the position of the first element with a value greater than val in the [first, last) range of an array or container. If it is an array, it returns the pointer of the position; if it is a container, it returns the iterator of the position.

Obviously, if there is no element to look for in the array or container, both lower_bound() and upper_bound() return a pointer or iterator where the element can be inserted (that is, where the element should be if it exists).

Examples are as follows:  

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int a[10] = { 1,2,2,3,3,3,5,5,5,5 };
	//Find - 1
	int* lowerPos = lower_bound(a, a + 10, -1);
	int* upperPos = upper_bound(a, a + 10, -1);
	printf("%d %d\n", lowerPos - a, upperPos - a);//Output 0 0

	//Find 1
	lowerPos = lower_bound(a, a + 10, 1);
	upperPos = upper_bound(a, a + 10, 1);
	printf("%d %d\n", lowerPos - a, upperPos - a);//Output 0 1

	//Find 3
	lowerPos = lower_bound(a, a + 10, 3);
	upperPos = upper_bound(a, a + 10, 3);
	printf("%d %d\n", lowerPos - a, upperPos - a);//Output 3 6

	//Find 4
	lowerPos = lower_bound(a, a + 10, 4);
	upperPos = upper_bound(a, a + 10, 4);
	printf("%d %d\n", lowerPos - a, upperPos - a);//Output 6

	//Find 6
	lowerPos = lower_bound(a, a + 10, 6);
	upperPos = upper_bound(a, a + 10, 6);
	printf("%d %d\n", lowerPos - a, upperPos - a);//Output 10
	return 0;
}

Obviously, if you only want to obtain the subscript of the element you want to check, you can directly subtract the first address of the array from the return value without using a temporary pointer.

[knocking on the blackboard]: here is a knowledge point, pointer pointer   = Number of elements between two pointers

Examples are as follows:

#include<stdio.h>
#include<algorithm>

using namespace std;

int main()
{
	int a[10] = { 1,2,2,3,3,3,5,5,5,5 };
	//Find 3
	printf("%d %d\n", lower_bound(a, a + 10, 3) - a, upper_bound(a, a + 10, 3) - a);//Output 3 6
	return 0;
}

5, Blue bridge conclusion: meet blue bridge meet you, not negative code, not negative Qing!

I hope it can help you. The code is not easy. It would be better if you could use your hands for three times. hh, I'll see you next time.

·

Topics: Algorithm