算法-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()
{
}
浙公网安备 33010602011771号