C + + learning notes (11): common containers in STL

Posted by Anarchatos on Thu, 10 Feb 2022 13:17:35 +0100


This blog post is a note taken when learning the C + + video of dark horse programmer. It is only convenient to review the old and know the new. It is not used for other purposes.

1, string container

1.1 basic concept of string

1. Essence:
String is a C + + style string, and string is essentially a class

2. The difference between string and char *:
(1) char * is a pointer;
(2) String is a class with char * encapsulated inside. It is a container of char * type to manage this string.

3. Features:
string encapsulates many methods
For example: find, copy, delete, replace, insert;
string manages the memory allocated by char * without worrying about copy out of bounds and value out of bounds. It is the responsibility of the class.

1.2 string constructor

Constructor prototype:

  • string(); // Create an empty string, such as string str;
  • string(const char* s); // Initialize with string s;
  • string(const string& str); // Initialize another string object with one string object;
  • string(int n,char c); // Initialize with n characters C;

Example:

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

//string construction
void test01()
{
    //string();// Create an empty string, such as string str;
    string s1; //Create an empty string and call the parameterless constructor
    cout << "str1 = " << s1 << endl;

    //string(const char* s);// Initialize with string s;
    const char* str = "hello world";
    string s2(str); //Put c_string converted to string
    cout << "str2 = " << s2 << endl;

    //String (const string & STR) / / use one string object to initialize another string object;
    string s3(s2); //Call copy constructor
    cout << "str3 = " << s3 << endl;

    //string(int n,char c);// Initialize with n characters C;
    string s4(10, 'c');
    cout << "str4 = " << s4 << endl;
}

int main()
{
    test01();
    return 0;
}

1.3 string assignment

Function Description: assign value to string.
Function prototype:

  • string& operator=(const char* s); // Char * type string is assigned to the current string
  • string& operator=(const string &s); // Assign the string s to the current string
  • string& operator=(char c); // The character assigned to the current string
  • string& assign(const char *s); // Assign the string s to the current string
  • string& assign(const char *s, int n); // Assign the first n characters of string s to the end of the current string character string
  • string& assign(const string &s); // Assign string s to the current string
  • string& assign(int n, char c); // Assign n characters C to the current string

Example:

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

//string assignment
void test01()
{
//    string& operator=(const char* s); // Char * type string is assigned to the current string
    string str1;
    str1 = "hello world!";
    cout<<"str1="<<str1<<endl;

//    string& operator=(const string &s); // Assign the string s to the current string
    string str2;
    str2 = str1;
    cout<<"str2="<<str2<<endl;

//    string& operator=(char c); // The character is assigned to the current string
    string str3;
    str3 = 'a';
    cout << "str3 = " << str3 << endl;

//    string& assign(const char *s); // Assign the string s to the current string
    string str4;
    str4.assign("hello c++");
    cout << "str4 = " << str4 << endl;

//    string& assign(const char *s, int n); // Assign the first n characters of string s to the current string
    string str5;
    str5.assign("hello c++",5);
    cout << "str5 = " << str5 << endl;

//    string& assign(const string &s); // Assign string s to the current string
    string str6;
    str6.assign(str5);
    cout << "str6 = " << str6 << endl;

//    string& assign(int n, char c); // Assign n characters C to the current string
    string str7;
    str7.assign(5, 'c');
    cout << "str7 = " << str7 << endl;
}

int main()
{
    test01();
    return 0;
}

1.4 string splicing

Function Description:
Realize string splicing at the end of string.
Function prototype:

  • string& operator+=(const char* str); // Overload + = operator
  • string& operator+=(const char c); // Overload + = operator
  • string& operator+=(const char* str); // Overload + = operator
  • string& append(const char *s); // Connects the string s to the end of the current string
  • string& append(const char *s, int n); // Connect the first n characters of string s to the end of the current string
  • string& append(const string &s); // Same as operator + = (const string & STR)
  • string& append(const string &s, int pos, int n); // N characters from POS in string s are connected to the end of the string

Example:

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

//String splicing
void test01()
{
//    Use "+ =" method
    string str1 = "I";
    str1 += "Love playing games";
    cout << "str1 = " << str1 << endl;//str1 = I love playing games

    str1 += ':';
    cout << "str1 = " << str1 << endl;//str1 = I love playing games:

    string str2 = "LOL DNF";
    str1 += str2;
    cout << "str1 = " << str1 << endl;//str1 = I love playing games: LOL DNF

//    Use append mode
    string str3 = "I";
    str3.append(" love ");
    str3.append("game abcde", 4);
    cout << "str3 = " << str3 << endl;//str3 = I love game

    str3.append(str2, 4, 3); // Starting from the subscript 4 position, intercept 3 characters of "LOL DNF" in str2 and splice them to the end of the string
    cout << "str3 = " << str3 << endl;//str3 = I love gameDNF
}

int main()
{
    test01();
    return 0;
}

1.5 string find and replace

Function Description:
1. Find: find whether the specified string exists;
2. Replace: replaces the string at the specified position.
Function prototype:

  • int find(const string& str, int pos = 0) const; // Find the location where STR appears for the first time, starting from POS
  • int find(const char* s, int pos = 0) const; // Find the location where s first appears, starting from POS
  • int find(const char* s, int pos, int n) const; // Find the first position of the first n characters of s from the POS position
  • int find(const char c, int pos = 0) const; // Find where the character c first appears
  • int rfind(const string& str, int pos = npos) const; // Find the last position of STR, starting from POS
  • int rfind(const char* s, int pos = npos) const; // Find the location of the last occurrence of S, starting from POS
  • int rfind(const char* s, int pos, int n) const; // Find the last position of the first n characters of s from POS
  • int rfind(const char c, int pos = 0) const; // Find the last occurrence of character c
  • string& replace(int pos, int n, const string& str); // Replace n characters starting from POS with string str
  • string& replace(int pos, int n,const char* s); // Replace the n characters starting from POS with the string s

Example:

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

//Find and replace
void test01()
{
    //1. Search
//    find() find from left to right
    string str1 = "abcdefgde";//Where a is position 0
//    int pos = str1.find("a");//pos = 0
    int pos = str1.find("de");
    if (pos == -1)
    {
        cout << "not found" << endl;
    }
    else
    {
        cout << "pos = " << pos << endl;
    }

//    rfind() look right to left
    pos = str1.rfind("de");
    cout << "pos = " << pos << endl;

}

void test02()
{
    //2. Replace
    string str1 = "abcdefgde";
    str1.replace(1, 3, "1111");//Three characters from position 1 and replace with "1111"
    cout << "str1 = " << str1 << endl;
}

int main()
{
    test01();
    test02();
    return 0;
}

1.6 string comparison

Function Description:
Comparison between strings.
Comparison method:
ASCL code comparison between strings.

 = Return 0; 
 > Return to 1;
 < return-1. 

Function prototype:

  • int compare(const string &s) const; // Compare with string s
  • int compare(const char *s) const; // Compare with string s

Example:

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

//string comparison
void test01()
{

    string str1 = "xello";
    string str2 = "hello";
    //Key: use compare to compare the Classl codes of two strings
    if (str1.compare(str2) == 0) {
        cout << "str1 be equal to str2" << endl;
    }
    else if (str1.compare(str2) > 0)
    {
        cout << "str1 greater than str2" << endl;
    }
    else
    {
        cout << "str1 less than str2" << endl;
    }
}

int main()
{
    test01();
    return 0;
}

1.7 string access

There are two ways to access a single string in a string:

  • char& operator[](int n); // Take characters by []
  • char& at(int n); // Get characters through at method

Example:

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

//String access
void test01()
{
    string str = "hello";

    for (int i = 0; i < str.size(); i++)
    {
        cout << str[i] << " ";//Key 1: access a single character through []
    }
    cout << endl;

    for (int i = 0; i < str.size(); i++)
    {
        cout << str.at(i) << " ";//Key 2: access a single character through at mode
    }
    cout << endl;

    //Modify single character
    str[0] = 'x';
    cout << str << endl;//xello
    str.at(1) = 'x';
    cout << str << endl;//xxllo
}
int main()
{
    test01();
    return 0;
}

1.8 string insertion and deletion

Function Description:
Insert and delete characters from a string
Function prototype:

  • string& insert(int pos, const char* s);// Insert string
  • string& insert(int pos, const string& str); // Insert string
  • string& insert(int pos, int n, char c);// Insert n characters in the specified position C
  • string& erase(int Pos, int n = npos); // Delete n characters starting from Pos

Example:

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

//String insertion and deletion
void test01()
{
    string str = "hello";
//    1. Insert key 1: insert();
    str.insert(1, "111");//From the first position, insert "111"
    cout << str << endl;//h111ello

//    2. Delete key: erase;
    str.erase(1, 3);  //Delete 3 characters from position 1
    cout << str << endl;//hello
}

int main()
{
    test01();
    return 0;
}

1.9 string substring

Function Description:
Get the desired substring from the string.
Function prototype:

  • string substr(int pos = 0, int n = npos) const;// Returns a string of n characters starting with POS

Example:

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

//string substring
void test01()
{

//    Key 1: substr()
    string str = "abcdefg";
    string subStr = str.substr(1, 3);//Intercept 3 characters from position 1
    cout << "subStr = " << subStr << endl;//subStr = bcd
}

void test02()
{
//   Example: get user name information from email address
    string email = "hello@sina.com";
    int pos = email.find("@");
    cout<<"@Location of:"<<pos<<endl;//@Location of: 5
    
    string username = email.substr(0, pos);
    cout << "username: " << username << endl;//username: hello
}

int main()
{
    test01();
    test02();
    return 0;
}

2, vector container

2.1 basic concept of vector

Function:
vector data structure is very similar to array, also known as single ended array.
The difference between vector and ordinary array:
The difference is that the array is a static space, while the vector can be extended dynamically.
Dynamic expansion:
1. Instead of connecting a new space after the original space, find a larger memory space, and then copy the metadata to the new space to release the original space.
2. The iterator of the vector container is an iterator that supports random access.

2.2 vector constructor

Function Description:
Create a vector container.
Function prototype:

  • vector v; // Using template implementation class implementation, default constructor
  • vector(v.begin(), v.end()); // Copy the elements in the v[begin(), end()) interval to itself.
  • vector(n, elem); // The constructor copies n elems to itself.
  • vector(const vector &vec);// Copy constructor.

Example:

#include <iostream>
using namespace std;
#include <vector>

void printVector(vector<int>& v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
    vector<int> v1; //Nonparametric structure
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);

    //It is constructed by interval
    vector<int> v2(v1.begin(), v1.end());
    printVector(v2);

    //Constructed by n elem ents
    vector<int> v3(10, 100);
    printVector(v3);

    //copy construction 
    vector<int> v4(v3);
    printVector(v4);
}

int main()
{
    test01();

    return 0;
}

2.3 vector assignment

Function Description:
Assign a value to the vector container.
Function prototype:

  • vector& operator=(const vector &vec);// Overloaded equal sign operator
  • assign(beg, end); // Assign the data copy in the [beg, end) interval to itself.
  • assign(n, elem); // Assign n elem copies to itself.

Example:

#include <iostream>
using namespace std;
#include <vector>

void printVector(vector<int>& v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//Assignment operation
void test01()
{
    vector<int> v1; //Nonparametric structure
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);

    vector<int>v2;
    v2 = v1;//Key 1: overload the equal sign operator
    printVector(v2);

    vector<int>v3;
    v3.assign(v1.begin(), v1.end());//Key 2: use assign(beg,end) to assign the data copy in the [beg, end) interval to itself.
    printVector(v3);

    vector<int>v4;
    v4.assign(10, 100); //Key 3: use assign(n, elem) to assign n elem copies to itself.
    printVector(v4);
}

int main()
{
    test01();

    return 0;
}

2.4 vector capacity and size

Function Description:
Operate on the capacity and size of the vector container.
Function prototype:

  • empty(); // Determine whether the container is empty
  • capacity(); // Capacity of container
  • size(); // Returns the number of elements in the container
  • resize(int num); // Reassign the length of the container to num. if the container becomes longer, the new location will be filled with the default value.
    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted.
  • resize(int num, elem); // Reassign the length of the container to num. if the container becomes longer, fill the new position with elem value.
    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted

Example:

#include <iostream>
using namespace std;
#include <vector>

void printVector(vector<int>& v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

// vector capacity and size
void test01()
{
    vector<int> v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);
//    Knowledge point 1: use empty() to judge whether the container is empty
    if (v1.empty())
    {
        cout << "v1 Empty" << endl;
    }
    else
    {
        cout << "v1 Not empty" << endl;
        cout << "v1 Capacity of = " << v1.capacity() << endl;//Knowledge point 2: use the capacity of the container
        cout << "v1 Size of = " << v1.size() << endl;//Knowledge point 3: size() returns the number of elements in the container
    }

    //Knowledge point 4: resize(int num, elem); Re specify the size. If the specified size is larger, the new position is filled with 0 by default. You can use the overloaded version elem to replace the default filling
    v1.resize(15,10);
    printVector(v1);

    //Knowledge point 5: resize(int num); Re specify the size. If the specified size is smaller, the excess elements will be deleted
    v1.resize(5);
    printVector(v1);
}

int main()
{
    test01();

    return 0;
}

2.5 vector insertion and deletion

Function Description:
Insert and delete the vector container.
Function prototype:

  • push_back(ele); // Tail insert element ele
  • pop_back(); // Delete last element
  • insert(const_iterator pos, ele); // The iterator points to the position POS and inserts the element ele
  • insert(const_iterator pos, int count,ele); // The iterator points to the position POS and inserts count elements ele
  • erase(const_iterator pos); // Delete the element pointed to by the iterator
  • erase(const_iterator start, const_iterator end); // Delete the elements of the iterator from start to end
  • clear(); // Delete all elements in the container

Example:

#include <iostream>
using namespace std;
#include <vector>

void printVector(vector<int>& v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

// vector insertion and deletion
void test01()
{
    vector<int> v1;
    //Knowledge point push: 1_ Back (ELE) insert element ele at the end
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    v1.push_back(40);
    v1.push_back(50);
    printVector(v1);

    //Knowledge point 2: pop_back() tail deletion
    v1.pop_back();
    printVector(v1);

    //Knowledge point 3: insert(const_iterator pos, ele) iterator points to position pos and inserts element ele
    v1.insert(v1.begin(), 100);
    printVector(v1);

//  Knowledge point 4: insert(const_iterator pos, int count,ele) iterator points to position pos and inserts count elements ele
    v1.insert(v1.begin(), 2, 1000);
    printVector(v1);

    //Knowledge point 5: erase(const_iterator pos) deletes the element pointed to by the iterator
    v1.erase(v1.begin());
    printVector(v1);

    //Knowledge point 6: erase(const_iterator start, const_iterator end) deletes the elements of the iterator from start to end
    v1.erase(v1.begin(), v1.end());
//    Knowledge point 7: clear() deletes all elements in the container
    v1.clear();
    printVector(v1);
}

int main()
{
    test01();

    return 0;
}

2.6 vector data access

Function Description:
Access the data of the vector container.
Function prototype:

  • at(int idx); // Returns the data indicated by the index idx
  • operator[]; // Returns the data indicated by the index idx
  • front(); // Returns the first data element in the container
  • back(); // Returns the last data element in the container

Example:

#include <iostream>
using namespace std;
#include <vector>

//vector data access
void test01()
{
    vector<int>v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }

    for (int i = 0; i < v1.size(); i++)
    {
        cout << v1[i] << " ";//Knowledge point 1: operator [] returns the data indicated by index idx
    }
    cout << endl;

    for (int i = 0; i < v1.size(); i++)
    {
        cout << v1.at(i) << " ";//Knowledge point 2: at(int idx) returns the data indicated by the index idx
    }
    cout << endl;

    cout << "v1 The first element of is: " << v1.front() << endl;//Knowledge point 3: front() returns the first data element in the container
    cout << "v1 The last element of the is: " << v1.back() << endl;//Knowledge point 4: back() returns the last data element in the container
}
int main()
{
    test01();

    return 0;
}

2.7 interchangeable containers

Function Description:
Realize the exchange of data in two containers.
Function prototype:

  • swap(vec); // Swap VEC with its own elements

Example:

#include <iostream>
using namespace std;
#include <vector>

void printVector(vector<int>& v)
{
    for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//vector interchange container
void test01()
{
    vector<int>v1;
    for (int i = 0; i < 10; i++)
    {
        v1.push_back(i);
    }
    printVector(v1);//0 1 2 3 4 5 6 7 8 9

    vector<int>v2;
    for (int i = 10; i > 0; i--)
    {
        v2.push_back(i);
    }
    printVector(v2);//10 9 8 7 6 5 4 3 2 1

    //Interchangeable container
    cout << "After exchange" << endl;
    v1.swap(v2);//Knowledge point 1: swap(vec) interchanges vec with its own elements
    printVector(v1);//10 9 8 7 6 5 4 3 2 1
    printVector(v2);//0 1 2 3 4 5 6 7 8 9
}

void test02()
{

    vector<int> v;
    for (int i = 0; i < 100000; i++)
    {
        v.push_back(i);
    }

    cout << "v The capacity of the is:" << v.capacity() << endl;//131072
    cout << "v The size of the is:" << v.size() << endl;//100000

    v.resize(3);//Reassign container length

    cout << "v The capacity of the is:" << v.capacity() << endl;//131072
    cout << "v The size of the is:" << v.size() << endl;//3

    //Practical use: shrink memory
    vector<int>(v).swap(v); //Anonymous object

    cout << "v The capacity of the is:" << v.capacity() << endl;//3
    cout << "v The size of the is:" << v.size() << endl;//3
}

int main()
{
    test01();
    test02();
    return 0;
}

2.8 reserved space for vector

Function Description:
Reduce the expansion times of vector when dynamically expanding capacity.
Function prototype:

  • reserve(int len); // The container reserves len element lengths. The reserved positions are not initialized and the elements are inaccessible.

Example:

#include <iostream>
using namespace std;
#include <vector>

//vector reserved space
void test01()
{
    vector<int> v;
    //Knowledge point 1: the reserve(int len) container reserves len element lengths. The reserved positions are not initialized and the elements are inaccessible.
    v.reserve(100000);

    int num = 0;
    int* p = NULL;
    for (int i = 0; i < 100000; i++)
    {
        v.push_back(i);
        if (p != &v[0])
        {
            p = &v[0];
            num++;
        }
    }
    cout << "num:" << num << endl;
}

int main()
{
    test01();

    return 0;
}

3, deque container

3.1 basic probability of deque container

Function:
Double ended array, which can insert and delete the head end.
The difference between deque and vector:
1. The insertion and deletion efficiency of vector is low for the head, and the larger the amount of data, the lower the efficiency;
2. deque relatively speaking, the insertion and deletion speed of the head is faster than that of the vector block;
3. vector accesses elements faster than deque, which is related to their internal implementation.
Internal working principle of deque:
1. deque has a central controller inside, which maintains the container in each buffer and stores real data in the buffer.
2. The central controller maintains the address of each buffer, which makes deque look like a continuous memory space.
3. The iterator of deque container also supports random access.

3.2 deque constructor

Function Description:
deque container construction.
Function prototype:

  • deque deqT; // Default construction form
  • deque(beg, end);// The constructor copies the elements in the [beg, end) interval to itself.
  • deque(n, elem);// The constructor copies n elems to itself.
  • deque(const deque &deq); // copy constructor

Example:

#include <iostream>
using namespace std;
#include <deque>

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//deque structure
void test01() {

//    Knowledge point 1: deque < T > deqt// Default construction form
    deque<int> d1;
    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeque(d1);//0 1 2 3 4 5 6 7 8 9

//    Knowledge point 2: deque(beg, end)// The constructor copies the elements in the [beg, end) interval to itself
    deque<int> d2(d1.begin(),d1.end());
    printDeque(d2);//0 1 2 3 4 5 6 7 8 9

//    Knowledge point 3: deque(n, elem)// The constructor copies n elems to itself
    deque<int>d3(10,100);
    printDeque(d3);//100 100 100 100 100 100 100 100 100 100

//    Knowledge point 4: deque (const deque & DEQ)// copy constructor 
    deque<int>d4 = d3;
    printDeque(d4);//100 100 100 100 100 100 100 100 100 100
}

int main()
{
    test01();

    return 0;
}

3.3 deque assignment

Function Description:
Assign a value to the deque container.
Function prototype:

  • deque& operator=(const deque &deq); // Overloaded equal sign operator
  • assign(beg, end);// Assign the data copy in the [beg, end) interval to itself.
  • assign(n, elem); // Assign n elem copies to itself.

Example:

#include <iostream>
using namespace std;
#include <deque>

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//deque assignment operation
void test01()
{
    deque<int> d1;
    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeque(d1);

//   Knowledge point 1: deque & operator = (const deque & DEQ)// Overloaded equal sign operator
    deque<int>d2;
    d2 = d1;
    printDeque(d2);

//    Knowledge point 2: assign(beg, end)// Assign the data copy in the [beg, end) interval to itself.
    deque<int>d3;
    d3.assign(d1.begin(), d1.end());
    printDeque(d3);

//   Knowledge point 3: assign(n, elem)// Assign n elem copies to itself.
    deque<int>d4;
    d4.assign(10, 100);
    printDeque(d4);

}

int main()
{
    test01();

    return 0;
}

3.4 deque size operation

Function Description:
Operate on the size of the deque container.
Function prototype:

  • deque.empty(); // Determine whether the container is empty
  • deque.size(); // Returns the number of elements in the container
  • deque.resize(num);// Reassign the length of the container to num. if the container becomes longer, the new location will be filled with the default value.
    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted.
  • deque.resize(num, elem); // Reassign the length of the container to num. if the container becomes longer, the new location will be filled with the default value.
    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted.
#include <iostream>
using namespace std;
#include <deque>

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//deque size operation
void test01()
{
    deque<int> d1;
    for (int i = 0; i < 10; i++)
    {
        d1.push_back(i);
    }
    printDeque(d1);

//    1, deque.empty(); // Determine whether the container is empty
    if (d1.empty()) {
        cout << "d1 Empty!" << endl;
    }
    else {
        cout << "d1 Not empty!" << endl;
//      2,deque.size(); // Returns the number of elements in the container
        cout << "d1 The size of the is:" << d1.size() << endl;
    }

//  3, deque.resize(num, elem);// Reassign size
    d1.resize(15, 1);
    printDeque(d1);

// 4, deque.resize(num);// Reassign size
    d1.resize(5);
    printDeque(d1);
}

int main()
{
    test01();

    return 0;
}

3.5 deque insertion and deletion

Function Description:

  • Insert and delete data into the deque container.

Function prototype:
1. Insert at both ends:

  • push_back(elem); // Add a data at the end of the container
  • push_front(elem);// Insert data in a header
  • pop_back();// Delete the last data in the container
  • pop_front(); // Delete first data of container

2. Specify location operation:

  • insert(pos,elem); // Insert a copy of the elem element in the POS position and return the location of the new data.
  • insert(pos,n,elem); // Insert n elem data in POS position, and there is no return value.
  • insert(pos,beg,end); // Insert the data of the [beg, end) interval in the POS position, and there is no return value.
  • clear();// Empty all data in the container
  • erase(beg,end); // Delete the data in the [beg, end) interval and return the position of the next data.
  • erase(pos); // Delete the data in POS position and return to the position of the next data.

Example:

#include <iostream>
using namespace std;
#include <deque>

//deque insert and delete
void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//1. Two end operation
void test01()
{
    deque<int> d;
//    1-1,push_back(elem); // Add a data at the end of the container
    d.push_back(10);
    d.push_back(20);
//    1-2,push_front(elem); // Insert a data in the head of the container
    d.push_front(100);
    d.push_front(200);

    printDeque(d);//200 100 10 20

//    1-3,pop_back(); // Delete the last data in the container
    d.pop_back();
//    1-4,pop_front(); // Delete first data of container
    d.pop_front();
    printDeque(d);//100 10
}

//2. Insert
void test02()
{
    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(100);
    d.push_front(200);
    printDeque(d);//200 100 10 20
//    2-1 insert(pos,elem); // Insert a copy of the elem element in the POS position and return the location of the new data.
    d.insert(d.begin(), 1000);
    printDeque(d);//1000 200 100 10 20
//    2-2 insert(pos,n,elem); // Insert n elem data in POS position, and there is no return value.
    d.insert(d.begin(), 2,10000);
    printDeque(d);//10000 10000 1000 200 100 10 20

    deque<int>d2;
    d2.push_back(1);
    d2.push_back(2);
    d2.push_back(3);
//    2-3 insert(pos,beg,end); // Insert the data of the [beg, end) interval in the POS position, and there is no return value.
    d.insert(d.begin(), d2.begin(), d2.end());
    printDeque(d);//1 2 3 10000 10000 1000 200 100 10 20

}

//delete
void test03()
{
    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(100);
    d.push_front(200);
    printDeque(d);//200 100 10 20
//    3-1 erase(pos); // Delete the data in POS position and return to the position of the next data.
    d.erase(d.begin());
    printDeque(d);//100 10 20
//    3-2 erase(beg,end); // Delete the data in the [beg, end) interval and return the position of the next data.
    d.erase(d.begin(), d.end());
//    3-3 clear(); // Empty all data in the container
    d.clear();
    printDeque(d);
}

int main()
{
    test01();
    test02();
    test03();

    return 0;
}

3.6 deque data access

Function Description:
Access to data in deque.
Function prototype:

  • at(int idx); // Returns the data indicated by the index idx
  • operator[]; // Returns the data indicated by the index idx
  • front();// Returns the first data element in the container
  • back(); // Returns the last data element in the container

Example:

#include <iostream>
using namespace std;
#include <deque>

void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//deque data access
void test01()
{
    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(30);
    d.push_front(40);

    for (int i = 0; i < d.size(); i++)
    {
//      1,  operator[]; // Returns the data indicated by the index idx
        cout << d[i] << " ";
    }
    cout << endl;


    for (int i = 0; i < d.size(); i++)
    {
//       2, at(int idx); // Returns the data indicated by the index idx
        cout << d.at(i) << " ";
    }
    cout << endl;

//    3,front(); // Returns the first data element in the container
    cout << "The first element is:" << d.front() << endl;//The first element is: 40
//    4,back(); // Returns the last data element in the container
    cout << "The last element is:" << d.back() << endl;//The last element is: 20
}

int main()
{
    test01();

    return 0;
}

3.7 deque sorting

Function Description:
deque containers are sorted by algorithm.
Function prototype:

  • sort(iterator beg, iterator end); // Sort the elements in the range of beg and end

Example:

#include <iostream>
using namespace std;
#include <deque>
#include <algorithm>

//deque sort
void printDeque(const deque<int>& d)
{
    for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{

    deque<int> d;
    d.push_back(10);
    d.push_back(20);
    d.push_front(300);
    d.push_front(400);

    printDeque(d);//400 300 10 20
//  1. sort(iterator beg, iterator end) / / sort the elements in the beg and end intervals
    sort(d.begin(), d.end());
    printDeque(d);//10 20 300 400

}
int main()
{
    test01();

    return 0;
}

4, stack container

4.1 basic concept of stack

Basic concepts:
There is only one kind of advanced data exit structure
matters needing attention:
1. Only the top elements in the stack can be used by the outside world, so the stack is not allowed to traverse.
2. Data entering the stack is called push
3. The pop-up data in the stack is called out of stack pop

4.2 common interfaces of stack

Function Description:
The common external interface of stack container.
Constructor:

  • stack stk;//stack is implemented by template class, which is the default construction form of stack object
  • stack(const stack &stk);// copy constructor

Assignment operation:

  • stack& operator=(const stack &stk); // Overloaded equal sign operator

Data access:

  • push(elem);// Add an element to the top of the stack
  • pop();// Remove the first element from the top of the stack
  • top(); // Return stack top element

Size operation:

  • empty(); // Determine whether the stack is empty
  • size(); // Returns the size of the stack

Example:

#include <iostream>
using namespace std;
#include <stack>

//Common interface of stack container
void test01()
{
    //Create stack container to meet the requirements of first in and last out
    stack<int> s;

//  1,push(elem); // Add an element to the top of the stack
    s.push(10);
    s.push(20);
    s.push(30);
    s.push(40);

    while (!s.empty())
    {
//      2,  top(); // Return stack top element
        cout << "Stack top elements are: " << s.top() << endl;
//      3,  pop(); // Remove the first element from the top of the stack
        s.pop();
    }
    cout << "The stack size is:" << s.size() << endl;
}

int main()
{
    test01();

    return 0;
}

5, queue container

5.1 basic concept of queue

Basic concepts:
Queue is a first in, first out data structure. It has two exits. In the queue, it is allowed to add elements from one end and remove elements from the other end.
matters needing attention:
1. Only the head and tail of the queue can be used by the outside world, so the queue is not allowed to traverse;
2. Incoming data in the queue is called - incoming push;
3. Outgoing data in the queue is called - outgoing pop.

5.2 common interfaces of queue

Function Description:
The common external interface of stack container.
Constructor:

  • queue que; //queue is implemented by template class, which is the default construction form of queue object
  • queue(const queue &que); // copy constructor

Assignment operation:

  • queue& operator=(const queue &que); // Overloaded equal sign operator

Data access:

  • push(elem);// Add elements to the end of the queue
  • pop(); // Remove the first element from the team head
  • back(); // Returns the last element
  • front();// Returns the first element

Size operation:

  • empty(); // Determine whether the stack is empty
  • size(); // Returns the size of the stack

Example:

#include <iostream>
using namespace std;
#include <queue>
#include <string>

class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

    string m_Name;
    int m_Age;
};

void test01()
{
    //Create queue
    queue<Person> q;

    //Prepare data
    Person p1("Tang Monk", 30);
    Person p2("Sun WuKong", 1000);
    Person p3("Zhu Bajie", 900);
    Person p4("Monk Sha", 800);

//    push(elem); // Add elements to the end of the queue
    q.push(p1);
    q.push(p2);
    q.push(p3);
    q.push(p4);

    while (!q.empty())
    {
//        front(); // Returns the first element
        cout << "Team head element-- full name: " << q.front().m_Name
             << " Age: "<< q.front().m_Age << endl;
//        back(); // Returns the last element
        cout << "Tail element-- full name: " << q.back().m_Name
             << " Age: " << q.back().m_Age << endl;

        cout << endl;
//        pop(); // Remove the first element from the team head
        q.pop();
    }

    cout << "The queue size is:" << q.size() << endl;
}

int main()
{
    test01();

    return 0;
}

6, list container

6.1 basic concepts

Function:
Chain store the data.
matters needing attention:
1. A linked list is a discontinuous storage structure on a physical storage unit. The logical order of data elements is realized through pointer links in the linked list.
2. Composition of linked list: the linked list is composed of a series of nodes.
3. Node composition: one is the data field for storing data elements, and the other is the pointer field for storing the address of the next node. The linked list in STL is a two-way circular linked list.
4. Because the storage mode of the linked list is not a continuous memory space, the iterator in the linked list only supports forward and backward, which belongs to a two-way iterator.
5. Advantages of list:
(1) Dynamic storage allocation is adopted, which will not waste and overflow memory again.
(2) It is very convenient to insert and delete the linked list. You can modify the pointer without moving a large number of elements.
6. Disadvantages of list:
The linked list is flexible, but it costs a lot of extra space (pointer field) and time (traversal).
7. List has an important property. Neither insert operation nor delete operation will cause the effectiveness of the original list iterator, which is not tenable in vector.
8. Summary: list and vector in STL are the two most commonly used containers, each with advantages and disadvantages.

6.2 list constructor

Function Description:
Create a list container.
Function prototype:

  • list lst; //list is implemented by template class, and the default construction form of object is:
  • list(beg,end); // The constructor copies the elements in the [beg, end) interval to itself.
  • list(n,elem); // The constructor copies n elems to itself.
  • list(const list &lst); // Copy constructor.

Example:

#include <iostream>
using namespace std;
#include <list>

void printList(const list<int>& L)
{
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

void test01()
{
//  1,list<T> lst; // List is implemented by template class, and the default construction form of object is:
    list<int>L1;
    //Add data
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    printList(L1);//10 20 30 40

//  2,  list(beg,end); // The constructor copies the elements in the [beg, end) interval to itself.
    list<int>L2(L1.begin(),L1.end());
    printList(L2);//10 20 30 40

//  3,  list(n,elem); // The constructor copies n elems to itself.
    list<int>L3(L2);
    printList(L3);//10 20 30 40

//  4,  list(const list &lst); // Copy constructor.
    list<int>L4(10, 1000);
    printList(L4);//1000 1000 1000 1000 1000 1000 1000 1000 1000 1000
}

int main()
{
    test01();

    return 0;
}

6.3 list assignment and exchange

Function Description:
Assign values to the list container and exchange list containers.
Function prototype:

  • assign(beg, end); // Assign the data copy in the [beg, end) interval to itself.
  • assign(n, elem); // Assign n elem copies to itself.
  • list& operator=(const list &lst); // Overloaded equal sign operator
  • swap(lst); // Swap LST with its own elements.

Example:

#include <iostream>
using namespace std;
#include <list>

void printList(const list<int>& L)
{
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//Assignment and exchange
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);

    //assignment
    list<int>L2;
// 1. operator = assignment
    L2 = L1;
    printList(L2);

    list<int>L3;
//  2,  assign(beg, end); // Assign the data copy in the [beg, end) interval to itself.
    L3.assign(L2.begin(), L2.end());
    printList(L3);

    list<int>L4;
//  3,  assign(n, elem); // Assign n elem copies to itself
    L4.assign(10, 100);
    printList(L4);

}

//exchange
void test02()
{

    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    list<int>L2;
    L2.assign(10, 100);

    cout << "Before exchange: " << endl;
    printList(L1);
    printList(L2);

    cout << endl;

//  4,  swap(lst); // Swap LST with its own elements.
    L1.swap(L2);

    cout << "After exchange: " << endl;
    printList(L1);
    printList(L2);

}

int main()
{
    test01();
    test02();
    return 0;
}

6.4 list size operation

Function Description:
Operate on the size of the list container.
Function prototype:

  • size(); // Returns the number of elements in the container
  • empty(); // Determine whether the container is empty
  • resize(num); // Reassign the length of the container to num. if the container becomes longer, the new location will be filled with the default value.
    / / if the container becomes shorter, the element whose end exceeds the length of the container will be deleted.
  • resize(num, elem);// Reassign the length of the container to num. if the container becomes longer, fill the new position with elem value.

Example:

#include <iostream>
using namespace std;
#include <list>

void printList(const list<int>& L)
{
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//Size operation
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
//  1,  empty(); // Determine whether the container is empty
    if (L1.empty())
    {
        cout << "L1 Empty" << endl;
    }
    else
    {
        cout << "L1 Not empty" << endl;
//  2,      size(); // Returns the number of elements in the container
        cout << "L1 The size of the is:" << L1.size() << endl;
    }

//  3,  resize(num); // Reassign the length of the container to num. if the container becomes longer, the new location will be filled with the default value.
    L1.resize(10);
    printList(L1);
//  4,  resize(num, elem); // Reassign the length of the container to num. if the container becomes longer, fill the new position with elem value.
    L1.resize(15,5);
    printList(L1);
}

int main()
{
    test01();

    return 0;
}

6.5 list insertion and deletion

Function Description:
Insert and delete data from the list container.
Function prototype:

  • push_back(elem);// Add an element at the end of the container
  • pop_back();// Delete the last element in the container
  • push_front(elem);// Insert an element at the beginning of the container
  • pop_front();// Remove the first element from the beginning of the container
  • insert(pos,elem);// Insert a copy of the elem element in the POS position and return the location of the new data.
  • insert(pos,n,elem);// Insert n elem data in POS position, and there is no return value.
  • insert(pos,beg,end);// Insert the data of the [beg, end) interval in the POS position, and there is no return value.
  • clear();// Remove all data from the container
  • erase(beg,end);// Delete the data in the [beg, end) interval and return the position of the next data.
  • erase(pos);// Delete the data in POS position and return to the position of the next data.
  • remove(elem);// Delete all elements in the container that match the element value.

Example:

#include <iostream>
using namespace std;
#include <list>

void printList(const list<int>& L)
{
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//list insert and delete
void test01()
{
    list<int> L;
    //1. Tail insertion
    L.push_back(10);
    L.push_back(20);
    L.push_back(30);
    //2. Head insert
    L.push_front(100);
    L.push_front(200);
    L.push_front(300);

    printList(L);

    //3. Tail deletion
    L.pop_back();
    printList(L);

    //4. Header deletion
    L.pop_front();
    printList(L);

    //5. Insert
    list<int>::iterator it = L.begin();
    L.insert(++it, 1000);
    printList(L);

    //6. Delete
    it = L.begin();
    L.erase(++it);
    printList(L);

    L.push_back(10000);
    L.push_back(10000);
    L.push_back(10000);
    printList(L);
//  7,  remove(elem);// Delete all elements in the container that match the element value.
    L.remove(10000);
    printList(L);

//  8. Empty
    L.clear();
    printList(L);
}


int main()
{
    test01();

    return 0;
}

6.6 list data access

Function Description:
Access the data in the list container.
Function prototype:

  • front(); // Returns the first element.
  • back(); // Returns the last element.

Example:

#include <iostream>
using namespace std;
#include <list>

//data access 
void test01()
{
    list<int>L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);

    //cout << L1. at(0) << endl;// Error: at access to data is not supported
    //cout << L1[0] << endl; // Error: accessing data in [] mode is not supported
//    Reason: the essence of a list is a linked list, rather than storing data in a continuous linear space

//  1,  front(); // Returns the first element.
    cout << "The first element is: " << L1.front() << endl;//The first element is: 10
//  2,  back(); // Returns the last element.
    cout << "The last element is: " << L1.back() << endl;//The last element is: 40

    //The iterator of the list container is a bidirectional iterator and does not support random access
    list<int>::iterator it = L1.begin();
    //it = it + 1;// Error, cannot skip access, even + 1
}

int main()
{
    test01();

    return 0;
}

6.7 inversion and sorting

Function Description:
Invert the elements in the container and sort the data in the container.
Function prototype:

  • reverse();// Reverse linked list
  • sort();// Linked list sorting

Example:

#include <iostream>
using namespace std;
#include <list>

void printList(const list<int>& L)
{
    for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

bool myCompare(int val1 , int val2)
{
    return val1 > val2;
}

//Reverse and sort
void test01()
{
    list<int> L;
    L.push_back(20);
    L.push_back(10);
    L.push_back(50);
    L.push_back(40);
    L.push_back(30);
    printList(L);//20 10 50 40 30

//  1,  reverse(); // Reverse linked list
    L.reverse();
    printList(L);//30 40 50 10 20

//  2,  sort(); // Linked list sorting
    L.sort(); //The default collation is from small to large
    printList(L);//10 20 30 40 50

    L.sort(myCompare); //Specify rules, from large to small
    printList(L);//50 40 30 20 10
}

int main()
{
    test01();

    return 0;
}

7, set/multiset container

7.1 basic concept of set

Introduction:
All elements are automatically sorted on insertion.
Essence:
set/multiset is an associative container, and its underlying structure is implemented by binary tree.
set/multiset differences:
set does not allow duplicate elements in the container;
multiset allows duplicate elements in a container.

Assignment and set construction

Function Description:
Create a set container and assign values.
Function prototype:
Construction:

  • set st; // Default constructor:
  • set(const set &st);// copy constructor
    Assignment:
  • set& operator=(const set &st); // Overloaded equal sign operator

Example:

#include <iostream>
using namespace std;
#include <set>

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//set construction and assignment
void test01()
{
//  1, set<T> st; // Default constructor:
    set<int> s1;

//    insert for inserting data
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
//    set insert data will be sorted automatically
    printSet(s1);//10 20 30 40

//  2,  set(const set &st); // copy constructor 
    set<int>s2(s1);
    printSet(s2);

//  3,  set& operator=(const set &st); // Overloaded equal sign operator
    set<int>s3;
    s3 = s2;
    printSet(s3);
}

int main()
{
    test01();

    return 0;
}

7.3 set size and swap

Function Description:
Count the size of set container and exchange set container.
Function prototype:

  • size(); // Returns the number of elements in the container
  • empty(); // Determine whether the container is empty
  • swap(st); // Swap two collection containers

Example:

#include <iostream>
using namespace std;
#include <set>

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}
/*set Size and swap*/

//size
void test01()
{

    set<int> s1;

    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);

//  1,  empty(); // Determine whether the container is empty
    if (s1.empty())
    {
        cout << "s1 Empty" << endl;
    }
    else
    {
        cout << "s1 Not empty" << endl;
//  2,      size(); // Returns the number of elements in the container
        cout << "s1 The size of the is: " << s1.size() << endl;
    }

}

//exchange
void test02()
{
    set<int> s1;

    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);

    set<int> s2;

    s2.insert(100);
    s2.insert(300);
    s2.insert(200);
    s2.insert(400);

    cout << "Before exchange" << endl;
    printSet(s1);//10 20 30 40
    printSet(s2);//100 200 300 400
    cout << endl;

    cout << "After exchange" << endl;
//  3,  swap(st); // Swap two collection containers
    s1.swap(s2);
    printSet(s1);//100 200 300 400
    printSet(s2);//10 20 30 40
}

int main()
{
    test01();
    test02();
    return 0;
}

7.4 set insertion and deletion

Function Description:
The set container inserts and deletes data.
Function prototype:

  • insert(elem);// Insert an element into the container.
  • clear(); // Clear all elements
  • erase(pos);// Delete the element referred to by the POS iterator and return the iterator of the next element.
  • erase(beg,end);// Delete all elements of the interval [beg, end], and return the iterator of the next element.
  • erase(elem); // Delete the element with element in the container.

Example:

#include <iostream>
using namespace std;
#include <set>

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//set insert and delete
void test01()
{
    set<int> s1;
//  1,  insert(elem); // Insert an element into the container.
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);
    printSet(s1);//10 20 30 40

//  2,  erase(pos); // Delete the element referred to by the POS iterator and return the iterator of the next element.
    s1.erase(s1.begin());
    printSet(s1);//20 30 40
    
//  3,  erase(elem); // Delete the element with element in the container.
    s1.erase(30);
    printSet(s1);//20 40

//  4,  erase(beg,end); // Delete all elements of the interval [beg, end], and return the iterator of the next element.
    //s1.erase(s1.begin(), s1.end());
    
//  5,  clear(); // Clear all elements
    s1.clear();
    printSet(s1);
}

int main()
{
    test01();
    return 0;
}

7.5 set search and statistics

Function Description:
Search the set container for data and statistics.
Function prototype:

  • find(key); // Find out whether the key exists. If so, return the iterator of the element of the key; If it does not exist, return set end();
  • count(key); // Count the number of key elements

Example:

#include <iostream>
using namespace std;
#include <set>

void printSet(set<int> & s)
{
    for (set<int>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

//set lookup and statistics
void test01()
{
    set<int> s1;
    //insert
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    s1.insert(40);

//  1,  find(key); // Find out whether the key exists. If so, return the iterator of the element of the key; If it does not exist, return set end();
    set<int>::iterator pos = s1.find(30);

    if (pos != s1.end())
    {
        cout << "Found element: " << *pos << endl;
    }
    else
    {
        cout << "Element not found" << endl;
    }

//  2,  count(key); // Count the number of key elements
    int num = s1.count(30);
    cout << "num = " << num << endl;
}

int main()
{
    test01();
    return 0;
}

7.6 differences between set and multiset

1. set cannot insert duplicate data, while multiset can.
2. When the set inserts data, it will return the insertion result, indicating that the insertion is successful.
3. multiset does not detect data, so duplicate data can be inserted.

Example:

#include <iostream>
using namespace std;
#include <set>

//Differences between set and multiset containers
void test01()
{
    set<int> s;
    pair<set<int>::iterator, bool>  ret = s.insert(10);
    if (ret.second)
    {
        cout << "First insertion successful!" << endl;
    }
    else
    {
        cout << "First insertion failed!" << endl;
    }

    ret = s.insert(10);
    if (ret.second) {
        cout << "The second insertion was successful!" << endl;
    }
    else {
        cout << "The second insertion failed!" << endl;
    }

    //multiset
    multiset<int> ms;
    ms.insert(10);
    ms.insert(10);

    for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

int main()
{
    test01();
    return 0;
}

7.7 pair group creation

Function Description:
Paired data. Using pair groups, you can return two data.
Function prototype:

  • pair<type, type> p ( value1, value2 );
  • pair<type, type> p = make_pair( value1, value2 );

Example:

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

//Create a group
void test01()
{
    pair<string, int> p("Tom", 20);
    cout << "full name: " <<  p.first << " Age: " << p.second << endl;

    pair<string, int> p2 = make_pair("Jerry", 30);
    cout << "full name: " << p2.first << " Age: " << p2.second << endl;
}

int main()
{
    test01();

    return 0;
}

7.8 set container sorting

Learning objectives:
set the default sorting rule is from small to large. Master how to change the sorting rule.
Main technical points:
The sorting rules can be changed by taking advantage of the cold and heat.

Example 1: set stores built-in data types

#include <iostream>
using namespace std;
#include <set>

class MyCompare
{
public:
    bool operator()(int v1, int v2)
    {
        return v1 > v2;
    }
};
void test01()
{
    set<int> s1;
    s1.insert(10);
    s1.insert(40);
    s1.insert(20);
    s1.insert(50);
    s1.insert(30);

    //The default order is from small to large
    for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    //Specifies the sort from large to small
    set<int,MyCompare> s2;
    s2.insert(10);
    s2.insert(40);
    s2.insert(20);
    s2.insert(50);
    s2.insert(30);

    for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
}

int main()
{
    test01();

    return 0;
}

Example 2: set stores user-defined data types

#include <iostream>
using namespace std;
#include <set>

class Person
{
public:
    Person(string name, int age)
    {
        this->m_Name = name;
        this->m_Age = age;
    }

    string m_Name;
    int m_Age;

};

class comparePerson
{
public:
    bool operator()(const Person& p1, const Person &p2)
    {
        //Sort by age
        return p1.m_Age > p2.m_Age;
    }
};

void test01()
{
    set<Person, comparePerson> s;

    Person p1("Liu Bei", 24);
    Person p2("Guan Yu", 28);
    Person p3("Fei Zhang", 25);
    Person p4("Zhao Yun", 21);

    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    s.insert(p4);

    for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << "full name: " << it->m_Name << " Age: " << it->m_Age << endl;
    }
}

int main()
{
    test01();

    return 0;
}

8, map/multimap container

8.1 basic concept of map

Introduction:
1. All elements in the map are pair
2. The first element in pair is key (key value), which serves as an index, and the second element is value (real value).
3. All elements are automatically sorted according to the key value of the element.
Essence:
map/multimap is an associative container, and its underlying structure is realized by yoga binary tree.
advantage:
You can quickly find the value value according to the key value.
Difference between map and multimap:
1. map does not allow duplicate key elements in the container;
2. multimap allows duplicate key elements in the container.

8.2 map construction and assignment

Function Description:
Construct and assign values to the map container.
Function prototype:
Construction:

  • map<T1, T2> mp; // Map default constructor:
  • map(const map &mp); // copy constructor
    Assignment:
  • map& operator=(const map &mp); // Overloaded equal sign operator

Example:

#include <iostream>
using namespace std;
#include <map>

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
//  1,  map<T1, T2> mp; // Map default constructor:
    map<int,int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));
    m.insert(pair<int, int>(4, 40));
    printMap(m);

//  2,  map(const map &mp); // copy constructor 
    map<int, int>m2(m); //copy construction 
    printMap(m2);

//  3,  map& operator=(const map &mp); // Overloaded equal sign operator
    map<int, int>m3;
    m3 = m2; //assignment
    printMap(m3);
}

int main()
{
    test01();

    return 0;
}

8.3 map size and swap

Function Description:
Count the size of map container and exchange map container.
Function prototype:

  • size(); // Returns the number of elements in the container
  • empty();// Determine whether the container is empty
  • swap(st); // Swap two collection containers

Example:

#include <iostream>
using namespace std;
#include <map>

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

void test01()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

//  1,  empty(); // Determine whether the container is empty
    if (m.empty())
    {
        cout << "m Empty" << endl;
    }
    else
    {
        cout << "m Not empty" << endl;
//   2,     size(); // Returns the number of elements in the container
        cout << "m The size of the is: " << m.size() << endl;
    }
}


//exchange
void test02()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

    map<int, int>m2;
    m2.insert(pair<int, int>(4, 100));
    m2.insert(pair<int, int>(5, 200));
    m2.insert(pair<int, int>(6, 300));

    cout << "Before exchange" << endl;
    printMap(m);
    printMap(m2);

    cout << "After exchange" << endl;
//  3,  swap(st); // Swap two collection containers
    m.swap(m2);
    printMap(m);
    printMap(m2);
}

int main()
{
    test01();
    test02();
    return 0;
}

8.4 map insertion and deletion

Function Description:
The map container inserts and deletes data.
Function prototype:

  • insert(elem); // Insert an element into the container.
  • clear(); // Clear all elements
  • erase(pos); // Delete the element referred to by the POS iterator and return the iterator of the next element.
  • erase(beg,end);// Delete all elements of the interval [beg, end], and return the iterator of the next element.
  • erase(elem);// Delete the element with key in the container.

Example:

#include <iostream>
using namespace std;
#include <map>

void printMap(map<int,int>&m)
{
    for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key = " << it->first << " value = " << it->second << endl;
    }
    cout << endl;
}

//map insertion and deletion
void test01()
{
    map<int, int> m;
    //First kind
    m.insert(pair<int, int>(1, 10));
    //Second
    m.insert(make_pair(2, 20));
    //Third
    m.insert(map<int, int>::value_type(3, 30));
    //Fourth
    m[4] = 40;
    printMap(m);

//    erase(pos); // Delete the element referred to by the POS iterator and return the iterator of the next element.
    m.erase(m.begin());
    printMap(m);
//    erase(key); // Delete the element with key in the container.
    m.erase(3);
    printMap(m);

//    erase(beg,end); // Delete all elements of the interval [beg, end], and return the iterator of the next element.
    m.erase(m.begin(),m.end());
//    clear(); // Clear all elements
    m.clear();
    printMap(m);
}

int main()
{
    test01();

    return 0;
}

8.5 map search and statistics

Function Description:
Search the map container for data and statistics.
Function prototype:

  • find(key); // Find out whether the key exists. If so, return the iterator of the element of the key; If it does not exist, return set end();
  • count(key); // Count the number of key elements

Example:

#include <iostream>
using namespace std;
#include <map>

//map lookup and statistics
void test01()
{
    map<int, int>m;
    m.insert(pair<int, int>(1, 10));
    m.insert(pair<int, int>(2, 20));
    m.insert(pair<int, int>(3, 30));

//  1,  find(key); // Find out whether the key exists. If so, return the iterator of the element of the key; If it does not exist, return set end();
    map<int, int>::iterator pos = m.find(3);

    if (pos != m.end())
    {
        cout << "Element found key = " << (*pos).first << " value = " << (*pos).second << endl;
    }
    else
    {
        cout << "Element not found" << endl;
    }

//  2,  count(key); // Count the number of key elements
    int num = m.count(3);
    cout << "num = " << num << endl;
}

int main()
{
    test01();

    return 0;
}

8.6 map container sorting

Learning objectives:
The default sorting rule of map container is to sort from small to large according to the key value. Master how to change the sorting rule

Main technical points:
Using the imitation function, the sorting rules can be changed

Example:

#include <iostream>
using namespace std;
#include <map>

class MyCompare
{
public:
    bool operator()(int v1, int v2)
    {
        return v1 > v2;
    }
};

//map container sorting
void test01()
{
    //Default sort from small to large
    //Sorting from large to small by using imitation function
    map<int, int, MyCompare> m;

    m.insert(make_pair(1, 10));
    m.insert(make_pair(2, 20));
    m.insert(make_pair(3, 30));
    m.insert(make_pair(4, 40));
    m.insert(make_pair(5, 50));

    for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++)
    {
        cout << "key:" << it->first << " value:" << it->second << endl;
    }
}

int main()
{
    test01();

    return 0;
}

Topics: C++ Container