算法-STL知识汇总

STL基本介绍

STL是C++提供的标准模版库,包含了很多的数据结构及算法的实现,平时进行算法练习时使用,能够节省很多的编码量和编码时间,非常好用,要使用STL,要了解以下几个基本概念:

    • 容器:可以把它理解为存放数据的地方,常用的一些容器有 链表(list) 栈(stack) 动态数组 (vector) 双端队列(deque) 队,列(queue) 映射(map)
    • 迭代器:(iterator):可以把它理解为指针类型,STL中的许多函数需要用到它们作为参数
    • 算法:它们通常需要与容器和游标配合使用,使用它们,你可以方便地对容器中的数据进行各种常见的操作,如排序操作,寻找最大元素的操作等

  C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。

STL基本操作

  vector 容器

头文件:#include<vector>

命名空间:using namespace std

功能介绍: vector是序列容器的一种,一个能够存放任意类型的动态数组,能够动态增删数据

1.构造函数

vector():创建一个空vector,返回vector对象
vector(int nSize):创建一个vector,元素个数为nSize,返回vector对象
vector(int nSize,const t& t):创建一个vector,元素个数为nSize,且值均为t,返回vector对象
vector(const vector&):复制构造函数,返回vector对象
vector(begin,end):复制[begin,end)区间内另一个数组的元素到vector中,返回vector对象  

2.增加函数

void push_back(const T& x):向量尾部增加一个元素X
iterator insert(iterator it,const T& x):向量中迭代器指向元素前增加一个元素x
iterator insert(iterator it,int n,const T& x):向量中迭代器指向元素前增加n个相同的元素x
iterator insert(iterator it,const_iterator first,const_iterator last):向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据

3.删除函数

iterator erase(iterator it):删除向量中迭代器指向元素
iterator erase(iterator first,iterator last):删除向量中[first,last)中元素
void pop_back():删除向量中最后一个元素
void clear():清空向量中所有元素

4.遍历函数

reference at(int pos):返回pos位置元素的引用
reference front():返回首元素的引用
reference back():返回尾元素的引用
iterator begin():返回向量头指针,指向第一个元素
iterator end():返回向量尾指针,指向向量最后一个元素的下一个位置
reverse_iterator rbegin():反向迭代器,指向最后一个元素
reverse_iterator rend():反向迭代器,指向第一个元素之前的位置

5.判断函数

bool empty() const:判断向量是否为空,若为空,则向量中无元素

6.大小函数

int size() const:返回向量中元素的个数
int capacity() const:返回当前向量张红所能容纳的最大元素值
int max_size() const:返回最大可允许的vector元素数量值

7.其他函数

void swap(vector&):交换两个同类型向量的数据
void assign(int n,const T& x):设置向量中第n个元素的值为x
void assign(const_iterator first,const_iterator last):向量中[first,last)中元素设置成当前向量元素

使用示例:

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    int arr[5] = { 1, 2, 3, 4, 5 };

    vector<int> arr0;
    vector<int> arr1(4);
    vector<int> arr2(4, 4);
    vector<int> arr3(arr2);
    vector<int> arr4 = arr0;
    vector<int> arr5 { 1, 2, 3, 4, 5, 6, 7 };    
    vector<int> arr6 = { 1, 2, 3, 4, 5, 6, 7 };    
    vector<int> arr7(arr5.begin(), arr5.end());
    vector<int> arr8(arr, arr + 5);

    vector<vector<int> > vec(4, vector<int>(4));

    for (int i = 0; i < 4; i++) {
        arr0.push_back(i);
    }

    arr0.insert(arr0.begin(), 6);
    arr0.insert(arr0.begin(), 6, 6);
    arr0.insert(arr0.begin(), arr2.begin(), arr2.end());

    arr0.erase(arr0.begin() + 3);
    arr0.erase(arr0.begin() + 3, arr0.begin() + 6);

    arr0.pop_back();
    arr0.clear();

    if (arr0.empty()) {
        arr0.push_back(1);
    }

    reverse(arr5.begin(), arr5.end());
    return 0;
}

vector的几种循环遍历方式: 

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    vector<int> arr{ 1, 2, 3, 4, 5};

    for (int i = 0; i < arr.size(); i++) {
        /* 通过下标遍历vector元素 */
        cout<<arr[i]<<endl;
    }

    for (vector<int>::const_iterator iter = arr.begin(); iter != arr.end(); iter++) {
        /* 通过迭代器遍历vector元素 */
        cout<<*iter<<endl;
    }

    for (auto iter = arr.begin(); iter != arr.end(); iter++) {
        /* 通过auto迭代器遍历vector元素 */
        cout<<*iter<<endl;
    }

    for (auto iter : arr) {
        /* 通过auto遍历vector元素,iter为元素内容,不是迭代器 */
        cout<<iter<<endl;
    }

    return 0;
}

string容器

头文件:#include <string>

命名空间:using namespace std

功能介绍: string严格来说也是序列容器的一种,用来表示字符串,能够动态增删数据

基本操作:

使用示例:

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

using namespace std;

int main()
{
    char str[] = "helloworld";
    
    string str0;
    string str1("helloworld");
    string str2(str1);
    string str3 = str2;
    string str4(5, 'a');
    string str5 = "helloworld";
    string str6 = string(10, 'z');

    /* 复制str的前5个字符 */
    string str7(str, 5);

    /* 取子串[1, 3) */
    string str8 = str7.substr(1, 3);

    /* 取子串[2, end) */
    string str9 = str7.substr(2);

    cout<<str2.compare(str1)<<endl; /* 0 */
    cout<<str2.compare(str4)<<endl; /* 7 */
    cout<<str2.compare(str6)<<endl; /* -18 */

    /*
     * size_t find ( const string& str, size_t pos = 0 ) const;
     * size_t find ( const char* s, size_t pos, size_t n ) const;
     * size_t find ( const char* s, size_t pos = 0 ) const;
     * size_t find ( char c, size_t pos = 0 ) const;
     */

    /* 查找str7在str1中首次出现的位置 */
    str1.find(str7);

    /* 查找"abc"在str1中首次出现的位置 */
    str1.find("abc");

    /* 从str1的第2个位置开始查找str7在str1中首次出现的位置 */
    str1.find(str7, 2);

    /* 从str1的第2个位置开始查找"abc"的前两个字符在str1中首次出现的位置,这里只能用常量字符串,不能用string */
    str1.find("abc", 2, 2);

    /*
     * size_t find_first_of ( const string& str, size_t pos = 0 ) const;
     * size_t find_first_of ( const char* s, size_t pos, size_t n ) const;
     * size_t find_first_of ( const char* s, size_t pos = 0 ) const;
     * size_t find_first_of ( char c, size_t pos = 0 ) const;
     */

    /* 查找“abc"中任意一个字符第一次出现的位置 */
    str1.find_first_of("abc");

    /*
     * size_t find_last_of ( const string& str, size_t pos = 0 ) const;
     * size_t find_last_of ( const char* s, size_t pos, size_t n ) const;
     * size_t find_last_of ( const char* s, size_t pos = 0 ) const;
     * size_t find_last_of ( char c, size_t pos = 0 ) const;
     */

    /* 查找“abc"中任意一个字符最后一次出现的位置 */
    str1.find_last_of("abc");

    /* 查找第一个不在"abc"中出现的字符 */
    str1.find_first_not_of("abc");

    /* 查找最后一个不在"abc"中出现的字符 */
    str1.find_last_not_of("abc");

    /* 使用str4替换从0开始的5个字符(aaaaaworld) */
    str1.replace(0, 5, str4);

    /* 使用str4的前4个字符替换从0开始的5个字符(aaaaworld) */
    str1.replace(0, 5, str4, 4);

    /* 使用str4的下标为1的字符开始的前4个字符替换从0开始的5个字符(aaaaworld) */
    str1.replace(0, 5, str4, 1, 2);

    /* 使用6个b替换从0开始的5个字符(bbbbbbworld) */
    str1.replace(0, 5, 6, 'b');

    str4.append(" world");
    str4.append(" world !!!", 6);
    str4.append(str1, 5, 5);
    str4.append(str1.begin() + 5, str1.end());

    /* 注意:迭代器标示位置不能插入字符串,只能插字符 */
    str4.insert(1, " world");
    str4.insert(str4.begin(), 'w');
    str4.insert(str4.begin(), 'w', 6);
    str4.insert(1, str1, 5, 5);
    str4.insert(str4.begin(), str1.begin() + 5, str1.end());

    str4.erase(5, 5);
    str4.erase(str4.begin());
    str4.erase(str4.begin(), str4.end());

    /* 字符串反转 */
    reverse(str5.begin(), str5.end());
    return 0;
}

 list容器

  头文件:#include <list>

  命名空间:using namespace std

  功能介绍: list是序列容器的一种,一个能够存放任意类型的动态数组,能够动态增删数据

  基本操作:

1.构造函数

list<T> lst; list采用模板类实现对象的默认构造形式:
list(beg,end); 构造函数将[beg, end)区间中的元素拷贝给本身。
list(n,elem); 构造函数将n个elem拷贝给本身。
list(const list &lst); 拷贝构造函数

2.增加函数

assign() 给list赋值
insert() 插入一个元素到list中
push_back() 在list的末尾添加一个元素
push_front() 在list的头部添加一个元素

3.删除函数

pop_back() 删除最后一个元素
pop_front() 删除第一个元素
clear() 删除所有元素
erase() 删除一个元素
unique() 删除list中重复的元素

4.遍历函数

front() 返回第一个元素
back() 返回最后一个元素
begin() 返回指向第一个元素的迭代器
end() 返回末尾的迭代器
rbegin() 返回指向第一个元素的逆向迭代器
rend() 指向list末尾的逆向迭代器

5.判断函数

bool empty() const:判断list是否为空,若为空,则向量中无元素

6.操作函数

get_allocator() 返回list的配置器
max_size() 返回list能容纳的最大元素数量
merge() 合并两个list
remove() 从list删除元素
remove_if() 按指定条件删除元素
resize() 改变list的大小
reverse() 把list的元素倒转
size() 返回list中的元素个数
sort() 给list排序
splice() 合并两个list
swap() 交换两个list

使用示例:

#include<iostream>
#include<list>

using namespace std;

int main()
{
}

 

stack容器

头文件:#include<stack>

命名空间:using namespace std

功能介绍: stack是序列容器的一种,其实现为常用的数据结构栈的的库函数实现,本质是一个能够存放任意类型的动态数组,能够动态增删数据,但是遵循后进先出(LIFO)的规则,限制了插入和删除只能在一个位置上进行,在dfs、单调栈等算法中的应用比较典型

基本操作:

empty() 判断栈是否为空

pop() 移除栈顶元素

push() 在栈顶增加元素

size() 返回栈中元素数目

top() 返回栈顶元素

使用示例:

#include<iostream>
#include<stack>

using namespace std;

int main()
{
}

 

 queue容器

头文件:#include <queue>

命名空间:using namespace std

功能介绍: queue是序列容器的一种,其实现为常用数据结构队列的实现,本质是一个能够存放任意类型的动态数组,能够动态增删数据,但是遵循先进先出(FIFO)的规则,限制了入队和出队顺序,在bfs算法中的应用比较典型

基本操作:

push() 入队操作,压入队列的末端

pop() 出队操作,弹出队列的第一个元素(队顶元素),注意此函数并不返回任何值

front() 返回第一个元素(队顶元素)

back() 返回最后一个元素(队尾元素)

empty() 判断队列是否为空

size() 返回队列的长度

使用示例:

#include<iostream>
#include<queue>

using namespace std;

int main()
{
}

 

 priority_queue容器

  头文件:#include<priority_queue>

命名空间:using namespace std

功能介绍: priority_queue是序列容器的一种,一个能够存放任意类型的动态数组,算是queue的特殊实现,能够动态增删数据,priority_queue是一个基于优先级的无界优先级队列,其元素按照其自然顺序进行排序,或者根据构造队列时提供的comparator进行排序,具体取决用使用场景及使用的构造方法

  基本操作:

empty() 如果队列为空返回真

pop() 删除对顶元素

push() 加入一个元素

size() 返回优先队列中拥有的元素个数

top() 返回优先队列对顶元素

使用示例:

#include<iostream>
#include<priority_queue>

using namespace std;

int main()
{
}

 

 pair容器

  头文件:#include<utility>

命名空间:using namespace std

类模板:template<class T1,class T2> struct pair

功能介绍: pair是STL提供的一种类似key-value的数据结构,通常将两个数据项组合成一组数据,pair的实现是一个结构体,主要的两个成员变量是first、second,pair是一个struct,不是class,故可以直接使用pair的成员变量一个能够存放任意类型的动态数组,能够动态增删数据

使用示例:

#include<iostream>
#include<utility>

using namespace std;

int main()
{
}

 

map

头文件:#include<map>

命名空间:using namespace std

功能介绍: map是STL提供的一种关联容器,是键/值对的数据结构实现,提供一种一对一的hash,map以模版(泛型)的方式实现,可以存储任意类型的数据,包括自定义类型,在map的内部实现中,自建了一棵红黑树,这棵树具有对数据自动排序的功能,故map内部所有的数据都是有序的,在map中可以动态增删数据

基本操作:

 

使用示例:

#include<iostream>
#include<map>

using namespace std;

int main()
{
}

 

multimap

头文件:#include<map>

命名空间:using namespace std

功能介绍: multimap是一种类似map的关联容器,可以保存重复的元素,multimap中会出现具有相同键值的元素序列,multimap大部分成员函数的使用方式和map相同,但是因为重复键的原因,multimap有一些函数的使用方式和map有一些区别。

使用示例:

#include<iostream>
#include<map>

using namespace std;

int main()
{
}

 

unordered_map

头文件:#include<map>

命名空间:using namespace std

功能介绍:unordered_map是一种类似map的关联容器,不同的是unordered_map不会根据key的大小进行排序,存储时是根据key的hash值判断元素是否相同,即unordered_map内部元素是无序的。unordered_map的底层实现是一个防冗余的哈希表(开链法避免地址冲突)。unordered_map的key需要定义hash_value函数并且重载operator ==。哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,时间复杂度为O(1),代价则是要消耗比较多的内存。哈希表的查询时间虽然是O(1),但是并不是unordered_map查询时间一定比map短,因为实际情况中还要考虑到数据量,而且unordered_map的hash函数的构造速度也没那么快,所以不能一概而论,应该具体情况具体分析。

使用示例:

#include<iostream>
#include<map>

using namespace std;

int main()
{
}

 

set

头文件:#include<set>

命名空间:using namespace std

功能介绍: set是STL提供的一种关联容器,set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序,需要注意的是set中数元素的值不能直接被改变。

基本操作:

begin() 返回set容器的第一个元素

end()  返回set容器的最后一个元素

clear()  删除set容器中的所有的元素

empty() 判断set容器是否为空

max_size() 返回set容器可能包含的元素最大个数

size()  返回当前set容器中的元素个数

rbegin() 返回的值和end()相同

rend() 返回的值和rbegin()相同

使用示例:

#include<iostream>
#include<set>

using namespace std;

int main()
{
}

 

multiset

头文件:#include<set>

命名空间:using namespace std

功能介绍: pair是STL提供的一种类似key-value的数据结构,通常将两个数据项组合成一组数据,pair的实现是一个结构体,主要的两个成员变量是first、second,pair是一个struct,不是class,故可以直接使用pair的成员变量一个能够存放任意类型的动态数组,能够动态增删数据

使用示例:

#include<iostream>
#include<set>

using namespace std;

int main()
{
}

 

迭代器iterator

头文件:#include<iterator>

命名空间:using namespace std

功能介绍: 迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,一个迭代器可以是指向一定范围内的数组或者容器中的元素,具有在一定范围内数组进行迭代的操作集合,可以进行自增、自减运算,主要用于容器内元素遍历

使用示例:

#include<iostream>
#include<iterator>

using namespace std;

int main()
{
}

 

迭代器reverse_iterator

头文件:#include<iterator>

命名空间:using namespace std

功能介绍: 逆向迭代器(iterator)是迭代器的一种,可以逆序检查容器内元素并遍历元素的数据类型,也可以进行自增、自减运算,主要用于容器内元素遍历

使用示例:

#include<iostream>
#include<iterator>

using namespace std;

int main()
{
}
posted @ 2020-08-17 23:44  斜风戏雨  阅读(143)  评论(0)    收藏  举报