Basic understanding of C++ STL

STL container

vector: A variable-sized array that supports fast random access and tail insertion and deletion. It is suitable for scenarios that require frequent insertion and deletion at the end and fast random access to elements.
deque: double-ended queue, supports insertion and deletion at the head and tail, and supports fast random access. It is suitable for scenarios that require insertion and deletion at the head and tail, and fast random access to elements.
list: Doubly linked list, supports insertion and deletion at any position, does not support random access. It is suitable for scenarios where elements need to be inserted and deleted at any position.
set/multiset: An ordered collection based on a red-black tree, which does not allow duplicate elements. It is suitable for scenarios where data needs to be stored in an orderly manner and duplicate elements are not allowed.
map/multimap: A mapping table based on a red-black tree, which supports sorting by key and does not allow duplicate keys. Each key corresponds to a value. Applicable to scenarios that require a mapping relationship and do not allow duplicate keys.
unordered_set/unordered_multiset: An unordered collection based on a hash table, allowing repeated elements. It is suitable for scenes that need to store and find elements quickly, and do not require elements to be ordered.
unordered_map/unordered_multimap: A mapping table based on a hash table, which allows repeated keys, and each key corresponds to a value. It is suitable for scenes that need to store and find elements quickly, and do not require elements to be ordered.

STL algorithm

sort: A sorting algorithm that supports sorting values, strings, and structures. unique: Deduplication algorithm, for ordered or unordered containers, removes adjacent or all identical elements.
find: search algorithm, supports finding whether the element is in the container, and returns an iterator pointing to the first found element or the end of the container. count: Counting algorithm, which supports counting the number of specified elements.
accumulate: Accumulation algorithm, which supports the accumulation of elements in the container with binary functions. transform: transformation algorithm, which supports functional transformation of elements in the container.
lower_bound/upper_bound: Find the element iterator closest to the specified element value, lower_bound returns the first element iterator greater than or equal to the specified value, upper_bound returns the first element iterator greater than the specified value.

To use STL, you need to include header files, such as including vector header files:

#include <vector>

The complete STL library header files include

<algorithm>, <array>, <bitset>, <complex>, <deque>, <exception>, <fstream>, <functional>, <iomanip>, <ios>, <iostream>, <istream>, <iterator>, <limits>, <list>, <locale>, <map>, <numeric>, <ostream>, <queue>, <set>, <sstream>, <stack>, <stdexcept>, <streambuf>, <string>, <tuple>, <typeinfo>, <unordered_map>, <unordered_set>, <utility>, <valarray>, <vector>

The C++ Standard Template Library (STL) is a set of C++ templates that provide rich, general-purpose functionality. It contains a variety of container types (vector, list, set, map, etc.) and various algorithms (sorting, searching, statistics, etc.). The most commonly used container types are vector and map.

The following are the usage methods and functions of some common STL functions:

1. Container type

a.std::vector<T>

vector is a dynamic array container type that expands and shrinks automatically. The following functions are available:

  • push_back(val): Add an element val at the end of the vector.
  • pop_back(): Remove an element from the end of the vector.
  • size(): Returns the size of the vector (that is, the number of elements).
  • clear(): Clears all elements in the vector.
  • begin(): Returns an iterator pointing to the first element of the vector.
  • end(): Returns an iterator pointing to the next position of the last element of the vector.
b.std::map<Key, Value>

map is an associative container type that stores a key-value pair, where the key is unique. The following functions are available:

  • insert({key, value}): Insert a key-value pair into the map.
  • erase(key): Delete a key-value pair of a specified key from the map.
  • find(key): Returns an iterator pointing to the location of the key.
  • size(): Returns the number of key-value pairs in the map.
  • clear(): Clear all key-value pairs in the map.
  • begin(): Returns an iterator pointing to the first key-value pair of the map.
  • end(): Returns an iterator pointing to the next position of the last key-value pair in the map.

2. Algorithms

a.sort(begin, end)

Use the sort function to sort the elements in an array or a container in ascending order. For example:

std::vector<int> vec = {5, 2, 9, 4, 8};
std::sort(vec.begin(), vec.end());

This will sort the vector in ascending order and the vec will become {2, 4, 5, 8, 9}.

b.binary_search(begin, end, val)

Use the binary_search function to perform a binary search on a container or an array. For example:

std::vector<int> vec = {2, 4, 5, 8, 9};
bool is_found = std::binary_search(vec.begin(), vec.end(), 8);

This will look for an element in vec with value 8, if found, is_found will be true, otherwise false.

c.count(begin, end, val)

Use the count function to count the number of elements with value val in a container or an array. For example:

std::vector<int> vec = {2, 4, 5, 8, 8, 9};
int count_8 = std::count(vec.begin(), vec.end(), 8);

This will count the number of elements in vec with value 8 and count_8 will be 2.

The above are the usage methods and functions of some common STL functions, and there are many other STL functions that can be used.

C++STL (Standard Template Library) is a powerful C++ standard library that is widely used in C++ development. STL contains a series of container, algorithm and iterator templates, which can speed up program development and improve program maintainability and scalability. The following is a C++ STL beginner tutorial to help you understand the basic syntax and operations of STL.

1. Common STL containers

STL containers are objects that store data and can store different types of data. C++STL provides a variety of containers, the following are some common STL containers:

  • vector: dynamic array, which can be automatically expanded.
  • list: Doubly linked list.
  • queue: First in first out queue.
  • stack: last in first out stack.
  • map: Associative container, providing the mapping function of key-value pairs.
  • set: Associative container, providing automatic sorting and deduplication functions.

2. Basic operation of the container

STL containers provide a wealth of methods and operations, the following are some common operations:

2.1. Container creation

To use an STL container, you need to include the corresponding header file first, and then declare variables through the container type, as follows:

#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

vector<int> myVec;          // 声明一个动态数组
list<double> myList;       // 声明一个双向链表
queue<char> myQueue;       // 声明一个字符型队列
stack<int> myStack;        // 声明一个整型堆栈
map<string, int> myMap;    // 声明一个键值对映射容器
set<int> mySet;            // 声明一个自动排序和去重的容器

2.2. Assignment and access to containers

STL containers provide a wealth of assignment and access methods, the following are some common operations:

myVec.push_back(10);         // 在动态数组尾部插入一个元素10
myList.push_front(3.14);     // 在双向链表头部插入一个元素3.14
myQueue.push('a');           // 在队列尾部插入一个字符a
myStack.push(100);           // 在堆栈顶部插入一个整数100
myMap["apple"] = 5;          // 在键值对容器中插入元素"apple-5"
mySet.insert(2);             // 在自动排序和去重容器中插入元素2

int num = myVec[0];          // 访问动态数组的第1个元素
double val = myList.front(); // 访问双向链表的第1个元素
char ch = myQueue.front();   // 访问队列的第1个元素
int top = myStack.top();     // 访问堆栈顶部的元素
int cnt = myMap["apple"];    // 根据键名获取键值对容器中的元素值
set<int>::iterator it = mySet.find(3); // 在自动排序和去重容器中查找元素3

2.3. Traversal and deletion of containers

STL containers provide a wealth of traversal and deletion methods, the following are some common operations:

// 遍历动态数组
for (int i = 0; i < myVec.size(); i++) {
    
    
    int val = myVec[i];
    cout << val << " ";
}

// 遍历双向链表
list<double>::iterator it = myList.begin();
while (it != myList.end()) {
    
    
    double val = *it;
    cout << val << " ";
    it++;
}

// 遍历队列
while (!myQueue.empty()) {
    
    
    char ch = myQueue.front();
    cout << ch << " ";
    myQueue.pop();  // 删除队列头部的元素
}

// 遍历堆栈
while (!myStack.empty()) {
    
    
    int top = myStack.top();
    cout << top << " ";
    myStack.pop();  // 删除堆栈顶部的元素
}

// 遍历键值对映射容器
map<string, int>::iterator it = myMap.begin();
while (it != myMap.end()) {
    
    
    string key = it->first;
    int val = it->second;
    cout << key << "-" << val << " ";
    it++;
}

// 遍历自动排序和去重容器
set<int>::iterator it = mySet.begin();
while (it != mySet.end()) {
    
    
    int val = *it;
    cout << val << " ";
    it++;
}

// 删除自动排序和去重容器中的元素3
mySet.erase(3);

3. Common STL algorithms

The STL algorithm is a series of algorithms for containers, which provide a wealth of calculation and operation methods. The following are some common STL algorithms:

3.1. for_each

for_each is an algorithm for traversing container elements, which can perform specified operations on each element in the container, as follows:

// 定义一个函数,输出容器元素
void print(int n) {
    
    
    cout << n << " ";
}

// 声明一个动态数组
vector<int> myVec = {
    
    1, 2, 3, 4, 5};

// 遍历动态数组,输出数组元素
for_each(myVec.begin(), myVec.end(), print);

3.2. sort

sort is a sorting algorithm that can sort the elements in the container as follows:

// 声明一个自动排序容器
set<int> mySet = {
    
    10, 5, 8, 1, 7};

// 对自动排序容器中的元素进行排序
sort(mySet.begin(), mySet.end());

// 遍历排序后的自动排序容器,输出容器元素
set<int>::iterator it = mySet.begin();
while (it != mySet.end()) {
    
    
    int val = *it;
    cout << val << " ";
    it++;
}

3.3. count

count is a counting algorithm that can count the number of elements in the container, as follows:

// 声明一个动态数组
vector<int> myVec = {
    
    1, 2, 1, 2, 3, 4, 1, 2};

// 统计动态数组中元素1出现的次数
int cnt = count(myVec.begin(), myVec.end(), 1);

// 输出元素1的出现次数
cout << cnt << endl;

The above is the basic syntax and operation of C++STL, I hope it will be helpful to you. If you want to learn more about STL, you can refer to other advanced tutorials.

1. Use queues to implement stacks (Question number: 225)

C++ basics: the use of STL container queue.
Use two queues to simulate the operation of the stack, to ensure that only one queue is not empty, the Push operation is always performed in the non-empty queue, and the Pop operation moves the elements in the non-empty queue to another empty queue one by one until the queue is only left An element can be popped.

2. Use stacks to implement queues (Question number: 232)

C++ basics: the use of STL container stack.
Use two stacks to simulate the operation of the queue, one stack for Push operations, and one stack for Pop operations. The Push operation directly pushes elements in the first stack, and the Pop operation needs to pop all the elements in the first stack to the second stack in turn, and then pop the elements in the second stack.

3. Valid brackets (question number: 20)

C++ basics: use of STL container stack, string manipulation.
Use the stack to match parentheses, traverse the string, if you encounter a left parenthesis, Push to the stack, if you encounter a right parenthesis, take out the top element of the stack for matching. If the match is successful, pop the top element of the stack, otherwise return false.

4. Design Circular Queue (Question Number: 622)

C++ basics: object-oriented programming, the use of arrays.
Use an array to store queue elements, and use two pointers head and tail to point to the head and tail of the queue respectively. If tail points to the last position of the array, it will point to the head again. If head and tail are the same, it means the queue is empty. If tail points to the previous position of head, it means the queue is full.

6. Minimum Stack (Question Number: 155)

C++ basics: the use of STL container stack.
Create two stacks, one for normal operations and the other for holding the minimum value after each operation. During the Push operation, the element is pushed to the normal stack, and the minimum value in the stack at this time is pushed to the minimum value stack. When the Pop operation is performed, the elements in the two stacks are popped at the same time.

7. Basic Calculator II (Question Number: 227)

C++ basics: use of STL container stack, string manipulation, expression evaluation.
Use the stack to process expressions, push each number to the stack, perform calculations when encountering symbols, and finally get the result of the expression.

8. Simplify the path (question number: 71)

C++ basics: use of STL container stack, string manipulation.
Use the stack to process the path and cut the path. If you encounter an empty path or "." to indicate the current directory, ignore it; if you encounter "..." to indicate the upper level directory, pop the top element of the stack; otherwise Push to the stack . The remaining elements in the final stack represent simplified paths.

9. Level order traversal of binary tree (question number: 102)

C++ basics: use of STL container queue, traversal of binary tree.
Use the queue for breadth-first traversal, first push the root node into the queue, then pop elements from the queue in turn, and push its child nodes into the queue. After traversing a layer, push the traversal result into a container, and finally return to this container.

10. Merge K sorted lists (question number: 23)

C++ basics: operation of linked list, use of STL container priority_queue.
Use a small root heap to merge K sorted linked lists, push the head element of each linked list into the heap, take out the top element of the heap each time, and push the next element of the linked list where the element is located into the heap until the heap is empty , at this time all linked lists are merged into a new ordered linked list.

11. Use the heap to implement sorting (question number: 347)

C++ basics: the use of STL container priority_queue.
Use the big root heap to implement sorting, first push all elements to the heap, and then take out the top elements of the heap one by one until the heap is empty. Every time an element is taken out, it means that the largest element has been found, and it can be placed in the result array.

12. Intersecting linked list (question number: 160)

C++ basics: operation of linked list.
First traverse the two linked lists separately, and record the length of the linked list. Then move the pointer of the long linked list back to the position as long as the short linked list, and then traverse the two linked lists synchronously, and find the first identical node, which is the intersection point.

13. Sorting Linked List (Question Number: 148)

C++ basics: operation of linked list, merge sort.
Use merge sort to sort the linked list, split the linked list into two sub-linked lists, sort the sub-linked lists separately, and then merge the two sorted sub-linked lists.

14. Reverse Linked List (Question Number: 206)

C++ basics: operation of linked list.
Traverse the linked list, use a variable to record the head of the linked list, every time a node is traversed, point the next node to the head of the linked list, and point the head of the linked list to this node, and finally the head node of the linked list is the tail node of the original linked list.

15. The penultimate k-th node in the linked list (Title: Sword Refers to Offer22)

C++ basics: operation of linked list.
Using the fast and slow pointers, first let the fast pointer move forward k steps, and then move forward at the same time until the fast pointer reaches the end of the linked list. At this time, the node pointed by the slow pointer is the kth node from the bottom of the linked list.

1. Use a queue to implement a stack (Question number: 225)

class MyStack {
    
    
public:
    /** Initialize your data structure here. */
    MyStack() {
    
    

    }
    
    /** Push element x onto stack. */
    void push(int x) {
    
    
        q.push(x);
        for(int i=1; i<q.size(); i++){
    
    
            q.push(q.front());
            q.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        int x = q.front();
        q.pop();
        return x;
    }
    
    /** Get the top element. */
    int top() {
    
    
        return q.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return q.empty();
    }
private:
    queue<int> q;
};

2. Use stacks to implement queues (Question number: 232)

class MyQueue {
    
    
public:
    /** Initialize your data structure here. */
    MyQueue() {
    
    

    }
    
    /** Push element x to the back of queue. */
    void push(int x) {
    
    
        while(!s1.empty()){
    
    
            s2.push(s1.top());
            s1.pop();
        }
        s1.push(x);
        while(!s2.empty()){
    
    
            s1.push(s2.top());
            s2.pop();
        }
    }
    
    /** Removes the element from in front of queue and returns that element. */
    int pop() {
    
    
        int x = s1.top();
        s1.pop();
        return x;
    }
    
    /** Get the front element. */
    int peek() {
    
    
        return s1.top();        
    }
    
    /** Returns whether the queue is empty. */
    bool empty() {
    
    
        return s1.empty();
    }
private:
    stack<int> s1,s2;
};

3. Valid brackets (question number: 20)

class Solution {
    
    
public:
    bool isValid(string s) {
    
    
        stack<char> stk;
        for(auto c : s){
    
    
            if(c == '(' || c == '[' || c == '{')
                stk.push(c);
            else{
    
    
                if(stk.empty())
                    return false;
                char top = stk.top();
                stk.pop();
                if(c == ')' && top != '(')
                    return false;
                if(c == ']' && top != '[')
                    return false;
                if(c == '}' && top != '{')
                    return false;
            }
        }
        return stk.empty();
    }
};

4. Design Circular Queue (Question Number: 622)

class MyCircularQueue {
    
    
public:
    /** Initialize your data structure here. Set the size of the queue to be k. */
    MyCircularQueue(int k) {
    
    
        size = k;
        front = 0;
        rear = 0;
        data.resize(size);
    }
    
    /** Insert an element into the circular queue. Return true if the operation is successful. */
    bool enQueue(int value) {
    
    
        if(isFull()) return false;
        data[rear] = value;
        rear = (rear+1)%size;
        return true;
    }
    
    /** Delete an element from the circular queue. Return true if the operation is successful. */
    bool deQueue() {
    
    
        if(isEmpty()) return false;
        front = (front+1)%size;
        return true;
    }
    
    /** Get the front item from the queue. */
    int Front() {
    
    
        if(isEmpty()) return -1;
        return data[front];
    }
    
    /** Get the last item from the queue. */
    int Rear() {
    
    
        if(isEmpty()) return -1;
        return data[(rear-1+size)%size];
    }
    
    /** Checks whether the circular queue is empty or not. */
    bool isEmpty() {
    
    
        return front == rear;
    }
    
    /** Checks whether the circular queue is full or not. */
    bool isFull() {
    
    
        return (rear+1)%size == front;
    }
private:
    vector<int> data;
    int front, rear, size;
};

5. Use queues to implement stack operations (question number: 225)

class MyStack {
    
    
public:
    /** Initialize your data structure here. */
    MyStack() {
    
    

    }
    
    /** Push element x onto stack. */
    void push(int x) {
    
    
        q.push(x);
        for(int i=1; i<q.size(); i++){
    
    
            q.push(q.front());
            q.pop();
        }
    }
    
    /** Removes the element on top of the stack and returns that element. */
    int pop() {
    
    
        int x = q.front();
        q.pop();
        return x;
    }
    
    /** Get the top element. */
    int top() {
    
    
        return q.front();
    }
    
    /** Returns whether the stack is empty. */
    bool empty() {
    
    
        return q.empty();
    }
private:
    queue<int> q;
};

6. Minimum Stack (Question Number: 155)

class MinStack {
    
    
public:
    /** initialize your data structure here. */
    MinStack() {
    
    

    }
    
    void push(int x) {
    
    
        s.push(x);
        if(min_s.empty() || x <= min_s.top()) 
            min_s.push(x);
    }
    
    void pop() {
    
    
        if(s.top() == min_s.top()) 
            min_s.pop();
        s.pop();
    }
    
    int top() {
    
    
        if(!s.empty())
            return s.top();
        return -1;
    }
    
    int getMin() {
    
    
        if(!min_s.empty())
            return min_s.top();
        return -1;
    }
private:
    stack<int> s, min_s;
};

7. Basic Calculator II (Question Number: 227)

class Solution {
    
    
public:
    int calculate(string s) {
    
    
        stack<int> stk;
        char sign = '+';
        int num = 0;
        // 对于最后一个操作数没有符号的情况
        s+="+";
        for(int i=0; i<s.size(); i++){
    
    
            char c = s[i];
            if(c>='0' && c<='9'){
    
    
                num = num*10 + (c-'0');
            }else if(c=='+' || c=='-' || c=='*' || c=='/'){
    
    
                if(sign=='+'){
    
    
                    stk.push(num);
                }else if(sign=='-'){
    
    
                    stk.push(-num);
                }else if(sign=='*'){
    
    
                    int tmp = stk.top();
                    stk.pop();
                    stk.push(tmp*num);
                }else if(sign=='/'){
    
    
                    int tmp = stk.top();
                    stk.pop();
                    stk.push(tmp/num);
                }
                sign = c;
                num = 0;
            }
        }
        int res = 0;
        while(!stk.empty()){
    
    
            res += stk.top();
            stk.pop();
        }
        return res;
    }
};

8. Simplify the path (question number: 71)

class Solution {
    
    
public:
    string simplifyPath(string path) {
    
    
        stringstream ss(path);
        vector<string> stk;
        string cur;
        while(getline(ss, cur, '/')){
    
    
            if(cur=="" || cur==".")
                continue;
            if(cur == ".."){
    
    
                if(!stk.empty())
                    stk.pop_back();
            }else{
    
    
                stk.push_back(cur);
            }
        }
        string res = "";
        for(auto str: stk)
            res += '/' + str;
        return res.empty() ? "/" : res;
    }
};

9. Level order traversal of binary tree (question number: 102)

class Solution {
    
    
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
    
    
        vector<vector<int>> res;
        if(!root){
    
    
            return res;
        }
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
    
    
            int level_size = q.size();
            vector<int> level;
            for(int i=0; i<level_size; i++){
    
    
                TreeNode* node = q.front();
                q.pop();
                level.push_back(node->val);
                if(node->left){
    
    
                    q.push(node->left);
                }
                if(node->right){
    
    
                    q.push(node->right);
                }
            }
            res.push_back(level);
        }
        return res;
    }
};

10. Merge K sorted lists (question number: 23)

class Solution {
    
    
public:
    ListNode* mergeKLists(vector<ListNode*>& lists) {
    
    
        if(lists.empty()){
    
    
            return NULL;
        }
        while(lists.size()>1){
    
    
            ListNode* l1 = lists.back();
            lists.pop_back();
            ListNode* l2 = lists.back();
            lists.pop_back();
            lists.push_back(mergeTwoLists(l1, l2));
        }
        return lists.front();
    }
private:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2){
    
    
        ListNode* dummy = new ListNode(-1);
        ListNode* cur = dummy;
        while(l1 && l2){
    
    
            if(l1->val <= l2->val){
    
    
                cur->next = l1;
                l1 = l1->next;
            }else{
    
    
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur->next;
        }
        if(l1){
    
    
            cur->next = l1;
        }else{
    
    
            cur->next = l2;
        }
        return dummy->next;
    }
};

11. Use the heap to implement sorting (question number: 347)

class Solution {
    
    
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
    
    
        unordered_map<int, int> mp;
        for(auto num: nums){
    
    
            mp[num]++;
        }
        priority_queue<pair<int, int>> pq;
        for(auto m: mp){
    
    
            pq.push(make_pair(m.second, m.first));
        }
        vector<int> res;
        while(k-- > 0){
    
    
            res.push_back(pq.top().second);
            pq.pop();
        }
        return res;
    }
};

12. Intersecting linked list (question number: 160)

class Solution {
    
    
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
    
    
        ListNode* l1 = headA;
        ListNode* l2 = headB;
        while(l1 != l2){
    
    
            l1 = l1 ? l1->next : headB;
            l2 = l2 ? l2->next : headA;
        }
        return l1;
    }
};

13. Sorting Linked List (Question Number: 148)

class Solution {
    
    
public:
    ListNode* sortList(ListNode* head) {
    
    
        if(!head || !head->next){
    
    
            return head;
        }
        ListNode* slow = head, *fast = head->next;
        while(fast && fast->next){
    
    
            slow = slow->next;
            fast = fast->next->next;
        }
        ListNode* mid = slow->next;
        slow->next = NULL;
        return merge(sortList(head), sortList(mid));
    }
private:
    ListNode* merge(ListNode* l1, ListNode* l2){
    
    
        ListNode* dummy = new ListNode(-1);
        ListNode* cur = dummy;
        while(l1 && l2){
    
    
            if(l1->val <= l2->val){
    
    
                cur->next = l1;
                l1 = l1->next;
            }else{
    
    
                cur->next = l2;

Guess you like

Origin blog.csdn.net/gezongbo/article/details/130174981