- 前言
- 迭代器Iterator
- 字符串类型string
- 顺序容器
- vector
- list
- deque
- 关联容器
- Set
- set
- unordered_set
- multiset*
- unordered_multiset*
- Map
- map
- unordered_map
- multimap*
- unordered_multimap*
- 容器适配器
- stack
- queue
- priority_queue
- pair
- tuple
- 算法
- 最大最小操作
- 排序
- 二分
- 数值转换
- 数字转字符串
- 字符串转数字
- 逆转元素顺序
- 其他
- auto
- 元素的遍历
- lambda表达式
- 总结
总结汇总一下使用c++进行刷题的时候,一些常用的STL容器、算法函数、语言特性、语法糖等。
有助于刷题的时候高效快速进行编码。
定义:迭代器是一种检查容器内元素并遍历元素的数据类型。
迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。
迭代器(Iterator)是指针(pointer)的泛化,指针可以用来遍历存储空间连续的数据结构,但是对于存储空间费连续的,就需要寻找一个行为类似指针的类,来对非数组的数据结构进行遍历,迭代器由此诞生。
迭代器的声明:
//以vector为例 vector字符串类型string::iterator it;//声明一个vector 类型的迭代器
c++内置字符串类型
构造函数:
string str; string str2(str);//拷贝str的值初始化str2
常用内置函数:
//1、front() 返回首字符
str.front()
//2、back()返回最后一个字符
str.back()
//3、data() 返沪指向字符串首部的指针,(相当于将string转为char[] ,返回数组地址)
str.data()
//4、empty() 字符串为空返回true
str.empty()
//5、size() or length()
str.size()//返回字符串长度
//6、erase()
str.erase(2)//移除第二个字符
str.erase(0,2)//移除第0-2的字符
str.erase(str.begin(),str.end())//移除所有字符
//7、insert()
str.insert(0,'a')//在第一个字符前面插入a
str.insert(str.beign(),'a')//在第一个字符前面插入a=
str.insert(0,2,'a')//在第一个字符前面插入两个a
//8、push_back() or append()
str.push_back('a') or str.append('a') //末尾添加
//9、pop_back()
str.pop_back()//弹出末尾字符
//10、starts_with
str.starts_with("aa")//是否以“aa”开头
//11、ends_with
str.ends_with("aa")//是否以“aa”结尾
//12、find()
str.find(str1)//在str中查找str1,找到返回起始下标,找不到返回string::npos (-1)
//13、replace()
str.replace("a","b")
//14、substr()获取字符串的子串
str.substr(1,7)//获取从下标为1的字符串开始长度为7的字符串
//15、stoi()字符串转整型
stoi("111")
//16、stol()字符串转长整型
stol("111")
//17、to_string()
to_string(100)
顺序容器
vector
vector以线性排列方式存储给定类型的元素,并允许快速随机访问任何元素。 当随机访问性能处于高级时,向量是序列的首选容器。
template> class vector
构造方法:
//空向量 vectorarr; //长度为10的整型向量,元素初值为0 vector arr(10); //长度为10,初值为1 vector arr(10,1); //使用另一个向量tmp初始化arr vector arr(tmp); //使用另一个向量的前三个元素初始化arr vector arr(b.begin(),b.begin()+3); //使用数组a的所有元素初始化arr int a[6]={1,2,3,4,5,6}; vector arr(a,a+6); //二维数组的初始化 vector > matrix(10,vector (10,1))//初始化10*10的二维数组,元素都为1
常用内置函数:
//1、assign,类似于重新初始化操作 arr.assign(6,6);//给arr赋值为6个值为6的元素 arr.assign(tmp.begin(),tmp.end());//将tmp所有元素赋值给arr //2、back() arr.back()//返回最后一个元素 //3、front() arr.front()//返回第一个元素 //4、push_back() arr.push_back(element) //给arr的后面追加元素element //5、pop_back() arr.pop_back()//弹出,丢弃最后一个元素 //6、clear() arr.clear()//清空所有元素 //7、empty() arr.empty()//判断是否为空,为空则true //8、erase() arr.erase(arr.begin()+3)//删除第4个元素 arr.erase(arr.begin()+3,arr.end())//删除第四个及以后的所有元素 //9、insert() arr.insert(arr.begin(),10)//在arr前面增加一个元素10 arr.insert(arr.begin(),tmp.begin(),tmp.end())//将tmp所有元素插到arr前面 //10、size() arr.size()//返回元素个数
注意:
- 该模板一般作为数组使用,支持[] 访问元素。
- 内置函数size() 尽量不要重复反复调用。
List是stl实现的双向链表,与向量(vectors)相比, 它允许快速的插入和删除,但是随机访问却比较慢。
template> class list
构造方法:
listlst1; //创建空list list lst1(10); //创建含有10个元素的list,值为0 list lst1(6,6); //创建含有6个元素值为6的list list lst1(lst2); //使用lst2初始化lst4 list lst1(lst2.begin(),lst2.begin()+6); //使用lst2前6个元素初始化
常用内置函数
//1、assign() list1.assign(6,6);//给arr赋值为6个值为6的元素 list1.assign(tmp.begin(),tmp.end());//将tmp所有元素赋值给arr //2、back() list1.back()//返回最后一个元素 //3、clear() list1.clear() //删除所有元素 //4、empty() list1.empty()//链表为空则返回true //5、erase() list1.erase(list1.begin()+3)//删除第三个元素 list1.erase(list1.begin(),list1.begin()+4)//删除前4个元素 //6、front() list1.front()// 返回第一个元素 //7、insert() list1.insert(list1.begin()+3,3)// 插入一个元素到list中第三个元素前面 //8、merge() list1.merge(list2)// 合并list1和list2 //9、 push_back() list1.push_back() 在list的末尾添加一个元素 //10、 push_front() list1.push_front() 在list的头部添加一个元素 //11、pop_back() list1.pop_back() 删除最后一个元素 //12、pop_front() list1.pop_front() 删除第一个元素 //13、resize list1.resize() //改变list的大小 //14、reverse() list1.reverse() //倒转链表 list1.size() 返回list中的元素个数 //15、sort() list1.sort()// 给list排序 //16、unique() list1.unique() 删除list中重复的元素deque
有下标顺序容器,它允许在其首尾两段快速插入及删除。另外,在 deque 任一端插入或删除不会非法化指向其余元素的指针或引用。
template> class deque
构造函数:
dequedq; //其他参考vector
常用内置函数:
//在vector的基础上增加了: //push_front() dq.push_front(element) //pop_front() dq.pop_front()关联容器 Set
集合类容器,有set,unordered_set,multiset
这类容器都有以下的构造方法以及常用函数(以set为例):
构造方法:
setse; set se(se1);
常用内置函数:
//1、empty() se.empty()//集合为空则返回true //2、size() se.size()//返回元素个数 //3、insert() se.insert(element)//插入一个元素 //4、erase() se.erase(element)//删除一个元素 //5、count() se.count(element)//查询集合中有多少个element,对于set和unordered_set,效果等同于contains //6、find() se.find(element)//查询element的位置 //7、contains() se.contains(element)//判断是否含有该元素 //8、lower_bound() se.lower_bound(element)//返回指向首个不小于给定键的元素的迭代器 //9、upper_bound() se.upper_bound(element)//返回指向首个大于于给定键的元素的迭代器 //10、clear() se.clear()set
std::set 是关联容器,含有 Key 类型对象的已排序集。用比较函数 比较 (Compare) 进行排序。搜索、移除和插入拥有对数复杂度。 set 通常以红黑树实现。
template<
class Key,
class Compare = std::less,
class Allocator = std::allocator > class set;
unordered_set
unordered_set 是含有 Key 类型唯一对象集合的关联容器。搜索、插入和移除拥有平均常数时间复杂度。
在内部,元素并不以任何特别顺序排序,而是组织进桶中。元素被放进哪个桶完全依赖其值的哈希。这允许对单独元素的快速访问,因为哈希一旦确定,就准确指代元素被放入的桶。
不可修改容器元素(即使通过非 const 迭代器),因为修改可能更改元素的哈希,并破坏容器。
template<
class Key,
class Hash = std::hash,
class KeyEqual = std::equal_to,
class Allocator = std::allocator
> class unordered_set;
multiset*
std::multiset 是含有 Key 类型对象有序集的容器。不同于 set ,它允许多个关键拥有等价的值。用关键比较函数 Compare 进行排序。搜索、插入和移除操作拥有对数复杂度。
template<
class Key,
class Compare = std::less,
class Allocator = std::allocator
> class multiset;
unordered_multiset*
unordered_multiset 是关联容器,含有可能非唯一 Key 类型对象的集合。搜索、插入和移除拥有平均常数时间复杂度。
元素在内部并不以任何顺序排序,只是被组织到桶中。元素被放入哪个桶完全依赖其值的哈希。这允许快速访问单独的元素,因为一旦计算哈希,它就指代放置该元素的准确的桶。
template<
class Key,
class Hash = std::hash,
class KeyEqual = std::equal_to,
class Allocator = std::allocator
> class unordered_multiset;
经验:
题目有有序的需求的时候,使用set,没有的话可以使用unordered_set,其余两个用的比较少,有需求的时候,自行查找资料,学习详细的使用方法。
哈希map类容器,主要有map,unordered_map,multimap,unordered_multimap
这类容器都有如下的常用构造方法以及内置函数(以map为例):
构造方法:
maphash_map; map hash_map(another_map);
常用内置函数:
//1、empty()
hash_map.empty()//
//2、size()
hash_map.size()//
//3、insert()
hash_map.insert({key,value})//插入键值对
//4、erase()
hash_map.erase(key)//删除某个键
//5、count()
hash_map.count(key)//返回匹配特定键的元素数量
//6、find()
hash_map.find(key)//查找给定键的位置,返回迭代器
//7、contains()
hash_map.contains(key)//检查容器是否含有带特定键的元素
//8、lower_bound()
hash_map.lower_bound(key)//返回指向首个不小于给定键的元素的迭代器
//9、upper_bound()
hash_map.upper_bound(key)//返回指向首个大于给定键的元素的迭代器
//10、clear()
hash_map.clear()
注意:
给map中插入元素使用更多的是这种形式:
hash_map[key]=valuemap
std::map 是有序键值对容器,它的元素的键是唯一的。用比较函数 Compare 排序键。搜索、移除和插入操作拥有对数复杂度。 map 通常实现为红黑树。
template<
class Key,
class T,
class Compare = std::less,
class Allocator = std::allocator >
> class map;
unordered_map
unordered_map 是关联容器,含有带唯一键的键-值 pair 。搜索、插入和元素移除拥有平均常数时间复杂度。
元素在内部不以任何特定顺序排序,而是组织进桶中。元素放进哪个桶完全依赖于其键的哈希。这允许对单独元素的快速访问,因为一旦计算哈希,则它准确指代元素所放进的桶。
template<
class Key,
class T,
class Hash = std::hash,
class KeyEqual = std::equal_to,
class Allocator = std::allocator< std::pair >
> class unordered_map;
multimap*
multimap 是关联容器,含有键值对的已排序列表,同时容许多个元素拥有同一键。按照应用到键的比较函数 Compare 排序。搜索、插入和移除操作拥有对数复杂度。
拥有等价键的键值对的顺序就是插入顺序,且不会更改。
template<
class Key,
class T,
class Compare = std::less,
class Allocator = std::allocator >
> class multimap;
unordered_multimap*
unordered_multimap 是无序关联容器,支持等价的关键(一个 unordered_multimap 可含有每个关键值的多个副本)和将关键与另一类型的值关联。 unordered_multimap 类支持向前迭代器。搜索、插入和移除拥有平均常数时间复杂度。
元素在内部不以任何特定顺序排序,而是组织到桶中。元素被放进哪个桶完全依赖于其关键的哈希。这允许到单独元素的快速访问,因为哈希一旦计算,则它指代元素被放进的准确的桶。
template<
class Key,
class T,
class Hash = std::hash,
class KeyEqual = std::equal_to,
class Allocator = std::allocator< std::pair >
> class unordered_multimap;
经验:
题目有有序的需求的时候,使用map,没有的话可以使用unordered_map,其余两个用的比较少,有需求的时候,自行查找资料,学习详细的使用方法。
template> class stack
构造方法:
stackstk;
常用内置函数:
stk.empty() //堆栈为空则返回真 stk.pop() //弹栈 stk.push() //入栈 stk.size() 返回栈中元素数目 stk.top() 返回栈顶元素queue
template> class queue
构造方法:
queueque;
常用内置函数:
que.empty() //堆栈为空则返回真 que.pop() //弹出队列首部 que.push() //入队列 que.size() 返回队列中元素数目 que.front() 返回栈顶元素priority_queue
优先队列,使用该类构造堆来满足需求
template, class Compare= less > class priority_queue // Type:元素类型 //Container:容器类型,默认为vector,一般不动 //Compare:元素的比较方式,决定是最大堆还是最小堆,默认最大堆
构造方法:
priority_queuepq;
常用内置函数:
//1、top() pq.top()//返回堆顶元素 //2、push() pq.push(element)//往堆中添加元素 //3、size() pq.size()//返回元素个数 //4、pop() pq.pop()//弹出堆顶元素 //5、empty() pq.empty()//堆为空则true
关于比较器
当元素类型是基本类型的时候(int,float,double...) 自定义最大最小堆使用lesspair和greater : priority_queue ,less > pq;//最大堆,可省略容器和比较器的指定 priority_queue ,greater > pq;//最小堆 当元素类型是自定义类型的时候,需要自定义比较器: 今有如下自定义类型Node struct Node{ int val; }; 自定义比较器,比较器内部重载()运算符: struct cmp{ bool operator() (Node* a,Node* b){ return a.val < b.val; //这个是生成最大堆,也就是降序,反之最小堆,升序 } } priority_queue ,cmp> pq;
template<
class T1,
class T2
> struct pair;
其实就是只有两个元素的结构体。
声明:
pairpa; pair pa;
元素访问:
int ele=pa.first//访问第一个元素 string str=pa.second//第二个元素 int ele=get<0>(pa)//访问第一个元素 string str=get<1>(pa)//第二个元素 int ele=get(pa)//访问第一个元素 string str=get (pa)//第二个元素
内置函数:
//1、make_pair pairtuplepa=make_pair(1,"a");
template< class... Types > class tuple;
类模板 std::tuple 是固定大小的异类值汇集。它是 std::pair 的推广。
声明:
tupletup; tuple tup;
元素访问:
int ele=get<0>(tup)//访问第一个元素 string str=get<1>(tup)//第二个元素 int ele=get(tup)//访问第一个元素 string str=get (tup)//第二个元素
内置函数:
//1、make_pair tuple算法 最大最小操作tup=make_tuple(1,"a",1.001);
max:
int a=10,b=11; int c=max(a,b);
max_element:
//1、数组则返回指针 int a[10]; int* max_one=max_element(a,a+10); //2、stl则返回迭代器 vectorarr; vector ::iterator max_one=max_element(arr.begin(),arr.end());
min:
int a=10,b=11; int c=min(a,b);
min_element:
//1、数组则返回指针 int a[10]; int* max_one=min_element(a,a+10); //2、stl则返回迭代器 vector排序arr; vector ::iterator max_one=min_element(arr.begin(),arr.end());
数组排序:
int a[10]; sort(a,a+10,cmp)
stl排序:
vectorarr; sort(a.begin(),a.end(),cmp)
自定义比较规则:
bool cmp(int a,int b){
return a>b;//降序
}
二分
lower_bound:
找到第一个大于等于target的元素的地址。
//1、数组 int* ptr=lower_bound(a,a+10,target); int* ptr2=lower_bound(a,a+10,target,cmp); //2、stl vector::iterator it1=lower_bound(arr.begin(),arr.end(),target); vector ::iterator it2=lower_bound(arr.begin(),arr.end(),target,cmp);
upper_bound:
找到第一个大于target的元素的地址。
//1、数组 int* ptr=upper_bound(a,a+10,target); int* ptr2=upper_bound(a,a+10,target,cmp); //2、stl vector数值转换 数字转字符串::iterator it1=upper_bound(arr.begin(),arr.end(),target); vector ::iterator it2=upper_bound(arr.begin(),arr.end(),target,cmp);
to_string:
to_string(1); to_string(1.01); to_string(-111111111);字符串转数字
stoi("111");//int
stol("1111");//long
stoll("1111");//long long
stof("1.01");//float
stod("1.01");//double
逆转元素顺序
int a[10]; reverse(a,a+10); vector其他 autoarr; reverse(arr.begin(),arr.end());
这个类型可以根据等式右边自动识别类型。
auto a=10; auto it=arr.begin(); //使用auto接tuple类型 auto tup=make_tuple(1,"a",2); auto [a,b,c]=make_tuple(1,"a",2);元素的遍历
搭配auto的map的遍历:
maphash_map; for(auto& [k,v] : hash_map){ }
其他类型:
vectorlambda表达式arr; for(auto& e : arr){ }
一般用来替代函数。
语法 :
auto fun1=[](Type type1,Type type2,...)->ReturnType{
//TODO--
return returnValue;
}
例子:
应用于排序替代自定义比较函数:
int a[10];
sort(a,a+10,[](int a,int b)->bool{
return a>b;
});
总结
上面介绍的只是各个知识点冰山一角,还有很多更丰富更奇特的用法,读者可以自己查资料。
谢谢。



