- 前言
- 迭代器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<int>::iterator it;//声明一个vector类型的迭代器
字符串类型string
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()//d出末尾字符
//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 Type, class Allocator = allocator<Type>>
class vector
构造方法:
//空向量
vector<int> arr;
//长度为10的整型向量,元素初值为0
vector<int>arr(10);
//长度为10,初值为1
vector<int>arr(10,1);
//使用另一个向量tmp初始化arr
vector<int>arr(tmp);
//使用另一个向量的前三个元素初始化arr
vector<int>arr(b.begin(),b.begin()+3);
//使用数组a的所有元素初始化arr
int a[6]={1,2,3,4,5,6};
vector<int> arr(a,a+6);
//二维数组的初始化
vector<vector<int>> matrix(10,vector<int>(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()//d出,丢弃最后一个元素
//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 Type, class Allocator= allocator<Type>>
class list
构造方法:
list<int>lst1; //创建空list
list<int> lst1(10); //创建含有10个元素的list,值为0
list<int>lst1(6,6); //创建含有6个元素值为6的list
list<int>lst1(lst2); //使用lst2初始化lst4
list<int>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 Type, class Allocator =allocator<Type>>
class deque
构造函数:
deque<int> dq;
//其他参考vector
常用内置函数:
//在vector的基础上增加了:
//push_front()
dq.push_front(element)
//pop_front()
dq.pop_front()
关联容器
Set
集合类容器,有set,unordered_set,multiset
这类容器都有以下的构造方法以及常用函数(以set为例):
构造方法:
set<int> se;
set<int> 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<Key>,
class Allocator = std::allocator<Key> > class set;
unordered_set
unordered_set 是含有 Key 类型唯一对象集合的关联容器。搜索、插入和移除拥有平均常数时间复杂度。
在内部,元素并不以任何特别顺序排序,而是组织进桶中。元素被放进哪个桶完全依赖其值的哈希。这允许对单独元素的快速访问,因为哈希一旦确定,就准确指代元素被放入的桶。
不可修改容器元素(即使通过非 const 迭代器),因为修改可能更改元素的哈希,并破坏容器。
template<
class Key,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>
> class unordered_set;
multiset*
std::multiset 是含有 Key 类型对象有序集的容器。不同于 set ,它允许多个关键拥有等价的值。用关键比较函数 Compare 进行排序。搜索、插入和移除 *** 作拥有对数复杂度。
template<
class Key,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>
> class multiset;
unordered_multiset*
unordered_multiset 是关联容器,含有可能非唯一 Key 类型对象的集合。搜索、插入和移除拥有平均常数时间复杂度。
元素在内部并不以任何顺序排序,只是被组织到桶中。元素被放入哪个桶完全依赖其值的哈希。这允许快速访问单独的元素,因为一旦计算哈希,它就指代放置该元素的准确的桶。
template<
class Key,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>
> class unordered_multiset;
经验:
题目有有序的需求的时候,使用set,没有的话可以使用unordered_set,其余两个用的比较少,有需求的时候,自行查找资料,学习详细的使用方法。
哈希map类容器,主要有map,unordered_map,multimap,unordered_multimap
这类容器都有如下的常用构造方法以及内置函数(以map为例):
构造方法:
map<int,int> hash_map;
map<int,int> 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]=value
map
std::map 是有序键值对容器,它的元素的键是唯一的。用比较函数 Compare 排序键。搜索、移除和插入 *** 作拥有对数复杂度。 map 通常实现为红黑树。
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
unordered_map
unordered_map 是关联容器,含有带唯一键的键-值 pair 。搜索、插入和元素移除拥有平均常数时间复杂度。
元素在内部不以任何特定顺序排序,而是组织进桶中。元素放进哪个桶完全依赖于其键的哈希。这允许对单独元素的快速访问,因为一旦计算哈希,则它准确指代元素所放进的桶。
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_map;
multimap*
multimap 是关联容器,含有键值对的已排序列表,同时容许多个元素拥有同一键。按照应用到键的比较函数 Compare 排序。搜索、插入和移除 *** 作拥有对数复杂度。
拥有等价键的键值对的顺序就是插入顺序,且不会更改。
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class multimap;
unordered_multimap*
unordered_multimap 是无序关联容器,支持等价的关键(一个 unordered_multimap 可含有每个关键值的多个副本)和将关键与另一类型的值关联。 unordered_multimap 类支持向前迭代器。搜索、插入和移除拥有平均常数时间复杂度。
元素在内部不以任何特定顺序排序,而是组织到桶中。元素被放进哪个桶完全依赖于其关键的哈希。这允许到单独元素的快速访问,因为哈希一旦计算,则它指代元素被放进的准确的桶。
template<
class Key,
class T,
class Hash = std::hash<Key>,
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator< std::pair<const Key, T> >
> class unordered_multimap;
经验:
题目有有序的需求的时候,使用map,没有的话可以使用unordered_map,其余两个用的比较少,有需求的时候,自行查找资料,学习详细的使用方法。
template <class Type, class Container= deque <Type>>
class stack
构造方法:
stack<int> stk;
常用内置函数:
stk.empty() //堆栈为空则返回真
stk.pop() //d栈
stk.push() //入栈
stk.size() 返回栈中元素数目
stk.top() 返回栈顶元素
queue
template <class Type, class Container = deque <Type>>
class queue
构造方法:
queue<int> que;
常用内置函数:
que.empty() //堆栈为空则返回真
que.pop() //d出队列首部
que.push() //入队列
que.size() 返回队列中元素数目
que.front() 返回栈顶元素
priority_queue
优先队列,使用该类构造堆来满足需求
template <class Type, class Container= vector<Type>, class Compare= less <typename Container ::value_type>>
class priority_queue
// Type:元素类型
//Container:容器类型,默认为vector,一般不动
//Compare:元素的比较方式,决定是最大堆还是最小堆,默认最大堆
构造方法:
priority_queue<int> pq;
常用内置函数:
//1、top()
pq.top()//返回堆顶元素
//2、push()
pq.push(element)//往堆中添加元素
//3、size()
pq.size()//返回元素个数
//4、pop()
pq.pop()//d出堆顶元素
//5、empty()
pq.empty()//堆为空则true
关于比较器
当元素类型是基本类型的时候(int,float,double...)
自定义最大最小堆使用less<type> 和greater<type>:
priority_queue<int,vector<int>,less<int>> pq;//最大堆,可省略容器和比较器的指定
priority_queue<int,vector<int>,greater<int>> pq;//最小堆
当元素类型是自定义类型的时候,需要自定义比较器:
今有如下自定义类型Node
struct Node{
int val;
};
自定义比较器,比较器内部重载()运算符:
struct cmp{
bool operator() (Node* a,Node* b){
return a.val < b.val; //这个是生成最大堆,也就是降序,反之最小堆,升序
}
}
priority_queue<Node*,vector<Node*>,cmp> pq;
pair
template<
class T1,
class T2
> struct pair;
其实就是只有两个元素的结构体。
声明:
pair<TYPE1,TYPE2> pa;
pair<int,string> pa;
元素访问:
int ele=pa.first//访问第一个元素
string str=pa.second//第二个元素
int ele=get<0>(pa)//访问第一个元素
string str=get<1>(pa)//第二个元素
int ele=get<int>(pa)//访问第一个元素
string str=get<string>(pa)//第二个元素
内置函数:
//1、make_pair
pair<int,string> pa=make_pair(1,"a");
tuple
template< class... Types >
class tuple;
类模板 std::tuple 是固定大小的异类值汇集。它是 std::pair 的推广。
声明:
tuple<TYPE1,TYPE2,TYPE3,...> tup;
tuple<int,string,double,...> tup;
元素访问:
int ele=get<0>(tup)//访问第一个元素
string str=get<1>(tup)//第二个元素
int ele=get<int>(tup)//访问第一个元素
string str=get<string>(tup)//第二个元素
内置函数:
//1、make_pair
tuple<int,string,douple> 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则返回迭代器
vector<int> arr;
vector<int>::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<int> arr;
vector<int>::iterator max_one=min_element(arr.begin(),arr.end());
排序
数组排序:
int a[10];
sort(a,a+10,cmp)
stl排序:
vector<int> arr;
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<int>::iterator it1=lower_bound(arr.begin(),arr.end(),target);
vector<int>::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<int>::iterator it1=upper_bound(arr.begin(),arr.end(),target);
vector<int>::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<int> arr;
reverse(arr.begin(),arr.end());
其他
auto
这个类型可以根据等式右边自动识别类型。
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的遍历:
map<int,string> hash_map;
for(auto& [k,v] : hash_map){
}
其他类型:
vector<int> arr;
for(auto& e : arr){
}
lambda表达式
一般用来替代函数。
语法 :
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;
});
总结
上面介绍的只是各个知识点冰山一角,还有很多更丰富更奇特的用法,读者可以自己查资料。
谢谢。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)