First acquaintance with STL
The birth of STL
For a long time, the software industry has been hoping to build something that can be reused; The object-oriented and generic programming idea of C + + aims to improve the reusability;
In most cases, data structures and algorithms fail to have a set of standards, resulting in being forced to do a lot of repetitive work;
In order to establish a set of standards for data structure and algorithm, STL was born;
STL basic concepts
● STL (Standard Template Library);
● STL is broadly divided into: container, algorithm and iterator;
● seamless connection between container and algorithm through iterator;
● almost all STL codes adopt template classes or template functions;
STL six components
● STL is generally divided into six components: container, algorithm, iterator, imitation function, adapter (adapter) and space configurator.
○ container: various data structures, such as vector, list, deque, set, map, etc., are used to store data;
○ algorithm: various commonly used algorithms, such as sort, find, copy and for_each et al;
○ iterator: acts as the glue between the container and the algorithm;
○ imitation function: the behavior is similar to the function, which can be used as a strategy of the algorithm;
○ adapter: something used to decorate the interface of a container or an emulator or iterator;
○ space configurator: responsible for space configuration and management;
Containers, algorithms, and iterators in STL
● container: a place to store things;
○ STL container is to implement some of the most widely used data structures;
○ common data structures: array, linked list, tree, stack, queue, set, mapping table, etc;
○ these containers are divided into sequential containers and associated containers:
■ sequential container: it emphasizes the sorting of values, and each element in the sequential container has a fixed position;
■ associative container: binary tree structure, and there is no strict physical order relationship between the elements;
● algorithm: the solution of the problem
○ limited steps to solve logical or mathematical problems. This discipline is called algorithm;
○ the algorithm is divided into:
■ qualitative change algorithm: refers to the content of elements in the interval that will be changed during the operation. For example, copy, replace, delete, etc;
■ non qualitative change algorithm: it means that the element content in the interval will not be changed during the operation, such as searching, counting, traversing, searching for extreme values, etc;
● iterators: adhesives between containers and algorithms
○ provide a method to find the elements contained in a container in order without exposing the internal representation of the container;
○ each container has its own exclusive iterator;
○ the use of iterators is very similar to pointers. At the beginning of learning, we can understand that iterators are pointers;
○ type of iterator:
type | function | Support operation |
---|---|---|
Input Iterator | Read only access to data | Read only + + / = = /= |
output iterators | Write only access to data | Write only++ |
forward iterators | Read and write operations, and can push the iterator forward | Read and write + + / = = /= |
Bidirectional Iterator | Read and write operations, and can operate forward and backward | Reading and writing + + /-- |
random access iterators | Read and write operation, which can access any data in a jumping way. It is the most powerful iterator | Reading and writing + + / -- / [n] / - N / < / < = / > / >= |
○ The types of iterators commonly used in containers are**Bidirectional Iterator **and**random access iterators **
Initial knowledge of container algorithm iterator
vector stores built-in data
● container: vector
● algorithm: for_each
● iterator: vector < int >:: iterator
//The vector container holds built-in data types #include <iostream> #include <vector> #include <algorithm> using namespace std; void method01(vector<int>& v) { vector<int>::iterator itBegin = v.begin();//Start iterator, pointing to the first element in the container vector<int>::iterator itEnd = v.end(); while (itBegin != itEnd) { cout << "The num is:" << *itBegin++ << endl; } } void method02(vector<int>& v) { for (vector<int>::iterator it = v.begin(); it != v.end(); it++) { cout << "The num from v is: " << *it << endl; } } void print(int value) { cout << value << endl; } void method03(vector<int>& v) { for_each(v.begin(), v.end(), print); } void test01() { //Create a vector container vector<int> v; //Insert data -- push_back(); v.push_back(0); v.push_back(1); v.push_back(2); //Accessing data in a container through iterators //Through the first method method01(v); //By the second method: method02(v); //The third method: method03(v); } int main() { test01(); return 0; } /* The num is:0 The num is:1 The num is:2 The num from v is: 0 The num from v is: 1 The num from v is: 2 0 1 2 */
The vector container holds user-defined data types
#include <iostream> #include <vector> #include <string> using namespace std; class Person { string name; int age; public: Person() {} Person(string name, int age) { this->name = name; this->age = age; } string getName() { return name; } int getAge() { return age; } }; void test01() { vector<Person>v; Person p1("a", 1); Person p2("b", 2); Person p3("c", 3); Person p4("d", 4); Person p5("e", 5); //Add data to container v.push_back(p1); v.push_back(p2); v.push_back(p3); v.push_back(p4); v.push_back(p5); //Traversal container for (vector<Person>::iterator it = v.begin(); it != v.end(); it++) { cout << "name is :" << (*it).getName() <<' ' << "age is:"<<(*it).getAge() << endl; } } int main() { test01(); return 0; } /* name is :a age is:1 name is :b age is:2 name is :c age is:3 name is :d age is:4 name is :e age is:5 */
Nested container
#include <iostream> #include <vector> #include <string> using namespace std; void test01() { vector<vector<int>> v; //Create a small container vector<int> v1; vector<int> v2; vector<int> v3; vector<int> v4; for (int i = 0; i < 4; i++) { v1.push_back(i + 1); v2.push_back(i + 2); v3.push_back(i + 3); v4.push_back(i + 4); } //Insert the small container into the large container v.push_back(v1); v.push_back(v2); v.push_back(v3); v.push_back(v4); //Traverse all data through large containers for (vector<vector<int>>::iterator it = v.begin(); it != v.end(); it++) { for (vector<int>::iterator intIt = (*it).begin(); intIt != (*it).end(); intIt++) { cout << *intIt << ' '; } cout << endl; } } int main() { test01(); return 0; } /* 1 2 3 4 2 3 4 5 3 4 5 6 4 5 6 7 */