C++STL学习

Standard Template Library (STL)

$1. Algorithms

<bits/stdc++>怎么包含?

MingW中:E:\MinGW\lib\gcc\mingw32\8.2.0\include\c++\mingw32\bits,由于有两个bits文件夹,必须选择这一个才行,另外一个不包含stdc++.h这个文件。


QT中:安装带有C和C++的各种运行环境,在以后使用到的时候可以直接在QT的安装文件夹中直接搜索就可以,

E:\Qt\Tools\mingw730_64\lib\gcc\x86_64-w64-mingw32\7.3.0\include\c++\x86_64-w64-mingw32\bits.


将以上两个得到的bits文件夹复制到VS的include文件夹中就可以:

D:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include.

1. Sorting


Link Sorting

The complexity of it is O(N*log(N)).

  1. sort (start_address, end_address)

start_address: the address of the first element of the array

and_address: the address of the next contigunous location of the last element of the array

  1. Acctually sort() sorts in the range of [start_address, end_address)
#include <iostream>
#include <algorithm>

using namespace std;

void show(int a[])
{
    for (int i = 0; i < 10; i++)
    {
        cout << a[i] << " ";
    }
}

int main()
{
    int a[10] = {1, 5, 8, 9, 6, 7, 3, 4, 2, 0};
    cout << "The array before sorting is: ";
    show(a);
    
    sort(a, a+10);
    cout << "\n\nThe array after sorting is: ";
    show(a);
    
    return 0;
}

2. Binary Search

Link Searching

  1. binary_search(start_address, end_address, value_to_find)

start_address: the address of the first element of the array.

end_address: the address of the last element of the array.

value_to_find: the target value which we have to search for.

  1. Range: binary_search[start_address, end_address]
/**
*CPP program to implement Binary Search in STL
*/
#include <iostream>
#include <algorithm>

using namespace std;

void show(int a[], int ary_size)
{
    for (int i = 0; i < ary_size; i++)
    {
        cout << a[i] << " ";
    }
}

int main()
{
    int a[] = { 1, 5, 8, 9, 6, 7, 3, 4, 2, 0 }; 
    int asize = sizeof(a) / sizeof(a[0]);
    cout << "The array is: ";
    show(a, asize);
    
    sort(a, a + asize);
    show(a, asize);
    
    if (binary_search(a, a + asize, 2))
    {
        cout << "\n2 is in array!" << endl;
    }
    else
    {
        cout << "Not found 2 in array!" << endl;
    }
    if (binary_search(a, a + asize, 10))
    {
        cout << "Find 10!" << endl;
    }
    else
    {
        cout << "Not found 10!" << endl;
    }
    
    return 0;
}

$2. Containers

实现了数据类型和算法的分离

1. pair

Link: Pair in C++ STL

Syntax: pair(data_type1, data_type2) Pair_name;

// CPP program to illustrate pair in STL
#include <iostream>
#include <utility>

using namespace std;

int main()
{
    pair<int, string> PAIR1;
    
    PAIR1.first = 3;
    PAIR1.second = "three";
    
    cout << PAIR1.first << " " << PAIR1.second << endl;
    
    return 0;
}

2. vector容器

Link Vector

动态数组:容器存放的元素是按值复制的方式进行,所以如果是类的话,就必须提供拷贝构造函数,从而保证对象间的拷贝正常

  • Iterators
  1. begin() – Returns an iterator pointing to the first element in the vector.

  2. end() – Returns an iterator pointing to the theoretical element that follows the last element in the vector.

  3. rbegin() – Returns a reverse iterator pointing to the last element in the vector (reverse begining). It moves from last to first element.

  4. rend() – Returns a reverse iterator pointing to the theoretical element preceding the first element in the vector (considered as reverse end).

  5. cbegin() – Returns a constant iterator pointing to the first element in the vector.

  6. cend() – Returns a constant iterator pointing to the theoretical element that follows the last element in the vector.

  7. crbegin() – Returns a constant iterator pointing to the last element in the vector (reverse begining). It moves from last to first element.

  8. cend() – Returns a constant reverse iterator pointing to the theoretical element preceding the first element in the vector (considered as reversed end).

  • Capacity
  1. size()

  2. max_size() – Returns the maximum number of the elements that the vector can hold.

  3. capacity() – Returns the size of the storage space currently allocated to the vector expressed as number of elements.

  4. resize(n) – Resize the container so that it contains ‘n’ elements.

  5. empty()

  6. shrink_to_fit() – Reduces the capacity of the container to fit its size and destroys all elements beyond the capacity.

  7. reverse() – Request that the veator capacity be at lease enough to contain n elements.

  1. push_back(num):将输入的num装进vector中,在尾部添加元素
vector<int> v(10);  // 没有写初始值,默认初始化为0
v.push_back(100);  // 在10个0的后面添加100
v.push_back(200); // 在100的后面添加200
  1. size()函数:获得vector的长度
  2. back():获取vector的尾部元素
  3. pop_back():删除vector的尾部元素
while (v.size() > 0)
{
    v.back() = 66;  // 修改尾部元素的值
    cout << v.back() << endl;
    v.pop_back();
}
  1. front():获取头部元素
    • 修改头部元素的值:v.front() = 12;
    • 函数返回值当左值,应该返回一个引用
  2. 通过数组的方式
// 写10的目的是:提前把内存准备好,不然会报错,无法通过下标访问元素:v[i]
vector<int> v(10, 0);  // 定义10个int大小的空间,并将所有的元素初始化为0

for (int i = 0; i < 10; i++)
{
    int temp;
    cin >> temp;
    v[i] = temp;  // 如果没有提前定义多少个大小的空间,无法通过下标进行访问
}
  1. 通过迭代器进行vector的遍历
vector<int> v(10);
for (int i = 0; i < 10; i++)
{
    v[i] = i + 1;
}
// 【说明】:当it == v.end()的时候,说明已经遍历完vector
// 即v.end()指向的是vector最后一个元素的下一个虚拟的位置,只是用来标记结束位置的
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
    cout << *it << endl;
}
  1. vector中元素的插入:
    • v.insert(v.begin(), 100);
    • v.insert(v.end(), 200);

3. string类

string的用法

  1. string的初始化

  2. string的遍历

    • 像字符数组一样操作,通过下标进行遍历
    • 通过迭代器进行遍历
    • at,s.at(i),区别在于at(i)可以捕获异常,在发生异常的时候(比如说数组越界的时候),at()能够捕获异常并继续运行,而直接通过下标进行索引的程序会被直接中断。
  3. string和其他字符类型的转换:

    • string --> char *, string s = “string”, char *str = s.c_str()
    • char * --> string, char *str = “string”, string s(str);
  4. string字符串的连接:

    • 直接用"+"进行连接
    • 使用string类自带的append()函数,s.append(s2)
  5. string字符串中查找子串:

    • find()函数:int index = s.find(“demo”, 0); // 从0开始查找,第一次出现"demo"的下标索引,下标从0开始的。
  6. string中对指定的字符串进行替换:

    • replace(ofindex, 3, “AAA”);
  7. insert(0, “AAA”), insert(s.length(), “123”);

  8. erase()

  9. transform(s.begin(), s.end(), s.begin(), 函数)

    即:操作的起始位置,操作完成后返回的字符串放置的位置,要对字符串进行操作的函数。

    其中函数可以是:

    • 函数的入口地址
    • 函数对象
    • 预定义的函数对象:比如toupper(所有的字母转换为大写),tolower
  10. length()函数:获取string的长度

4. iterator迭代器

【定义】:迭代器是一个“可遍历STL容器内全部或部分元素”的对象

  1. 迭代器指出容器中的一个特定的位置
  2. 迭代器就如同一个指针
  3. 迭代器提供对一个容器中的对象的访问方法,并且可以定义容器中对象的范围
  4. 分类
    • 输入迭代器:只写迭代器,往容器中写入元素,只能一次写入一个元素向前移动,只支持一遍算法,同一个迭代器不能两遍遍历一个序列
    • 输出迭代器:只读迭代器
    • 正向迭代器
    • 双向迭代器
  5. vector与迭代器的配合使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ArGVAXVC-1573288689324)(C:\Users\Xie Bailian\AppData\Roaming\Typora\typora-user-images\1573277989291.png)]

  1. 元素的删除:【注意】:当删除迭代器所指向的元素时,erase删除元素后悔自动将迭代器加1,并返回下一个迭代器的位置:it = v.erase(it);

    • 区间删除:
    v.erase(v.begin(), v.begin() + 3);
    
    • v.clear() 删除v中的所有元素
    • 指定位置删除:
    v.erase(v.begin());  // 删除头部元素
    
    • 删除指定的元素:
    for (vector<int>::iterator it = v.begin(); i != v.end();)
    {
        if (*it == n)
        {
            // 当删除迭代器所指向的元素时,erase删除元素后悔自动将迭代器加1,并返回下一个迭代器的位置
            it = v.erase(it);  
        }
        else
        {
            it++;
        }
    }
    

5. deque双端数组

  1. d.push_bacK()
  2. d.push_front()
  3. d.pop_back()
  4. d.pop_front()
  5. d.front()
  6. d.back()
  7. 查找元素对应的下标值:find(),返回一个迭代器
deque<int>::iterator it = find(d.begin(), d.end(), 33);
if (it != d.end())
{
    cout << "33对应的下标是:" << distance(d.begin(), it) << endl;
}
else
{
    cout << "没有找到值为33的元素!" << endl;
}
  1. distance(d.begin(), d.end())
    • 头文件:#include <algorithm>

6. stack容器

  • s.empty()

  • s.pop()

  • s.top()

  • s.push()

  • s.size()

7. queue队列

  • q.push()

  • q.front()

  • q.pop()

  • q.empty()

8. list双向链表

【定义】:双向链表容器,可以进行高效的插入删除元素

  • list不可以随机存取元素,因此不支持at(pos)和[]操作符,同时list的迭代器只能:it++ or it–,不能进行it += 5这种操作
  • l.push_back()
  • l.size()
  • l.insert()

【说明】:list双向链表插入元素时:是将指定的位置的元素及其之后的元素后移,新插入的元素代替之前在这个位置的元素

【说明】: 1.list双向链表插入元素时:是将指定的位置的元素及其之后的元素后移,新插入的元素代替之前在这个位置的元素; 2.list的index从0开始的。

l.insert(6, 100); // 在下标6的位置处插入元素100
// 0 1 2 3 4 5 6 7
// 0 1 2 3 4 5 100 6 7
  • l.clear() 删除list中的所有的元素
  • l.erase[begin, end)
    • 左闭右开!
    • 【注意】l.erase(l.begin(), l.begin() + 3)错误!不能使用begin() + 3,list不能随机存取元素!
  • l.erase(pos)
    • 删除pos位置的数据,返回下一个数据的位置
  • l.remove(elem)
    • 删除list容器中所有值与elem匹配的元素

9. priority_queue优先级队列

可分为最大值优先级队列(默认)和最小值优先级队列。

priority_queue<int> pq;  // 默认情况下是最大值优先级队列

// 定义最小值优先级队列,less:提前定义好的预定义函数,谓词
priority_queue<int, vector<int>, less<int>> pq1;
priority_queue<int, vector<int>, greater<int>> pq2; // 定义最大值优先级队列

while (pq.size() > 0)
{
    cout << pq.top() << endl;
    pq.pop();
}
  • push()
  • pop()
  • size()
  • top()

10. set和multiset集合

set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按照一定的顺序进行排列(默认递增)。

元素的插入过程是按照排序的规则进行插入的,因此不能指定插入的元素的位置。

set采用红黑树变体的数据结构实现,在插入和删除的操作上比vector快。

  • set不可以直接存取元素:不能使用at.(pos)和[]操作符
  • multiset与set的区别:
    • set支持唯一的键值,每个元素只能出现一次
    • multiset中,同一个值可以出现多次
  • 不能够直接修改set或者multiset容器中的值(这类容器是自动进行排序的),如果要修改元素值,必须先删除原来的元素,再将修改值插入到容器中即可
  • insert()
set<int> s;  // 默认为递增
set<int, less<int>> s1;  // 指定为递增
set<int, greater<int>> s2;  // 指定为递减

// 删除set集合中的元素
while (!s.empty())
{
    set<int>::iterator it = s.begin();
    cout << *it << " ";
    s.erase(s.begin());  // 删除当前元素,同时自动指向下一个元素
}

自定义的数据类型比较

仿函数的概念

class Student
{
  private:
    char name[20];
    int age;
    
  public:
    Student(char *name, int age)
    {
        strcpy(this->name, *name);
        this->age = age;
    }
};

// 创建仿函数
struct FuncStudent
{
    bool operator() (const Student &stu1, const Student &stu2)
    {
        // 定义递减规则
        return stu1.age > stu2.age;
    }
};

Student stu("dabai", 20);
set<Student, FuncStudent> s;
s.insert(stu);

// less和greater函数是已经定义好了的,可以直接使用,但只能够对基本的数据类型进行排序
  • find(elem)
    • 查找elem元素,返回指向elem元素的迭代器
  • count(elem)
    • 返回集合中elem元素的个数
  • lower_bound(elem)
    • 返回第一个>=elem元素的迭代器
  • upper_bound(elem)
    • 返回第一个>elem元素的迭代器
  • equal_range(elem)
    • 返回容器中与elem相等的上下限的两个迭代器,上限是闭区间,下限是开区间:[begin, end)
  • 以上函数返回两个迭代器,被封装在pari中

$3. Multimap

$4. CPP-Math

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值