1.vector
向量,又叫变长数组,当遇见只用普通数组会超内存的情况,使用vector会更便捷。 vector数组:可理解为两个维都可以变长的二维数组
#include<vector>;
using namespace std;
1.1定义
单独定义一个vector
vector<typename> name;
vector<vector<int> > name;
定义vector数组
vector<typename> Arrayname[arraysize];
比如
vector<int> vi[100];
1.2 访问
1.2.1 下标访问
vector<typename> vi;
直接访问方式:vi[0] vi[1]
1.2.2 迭代器访问
vector<typename>::iterator it;
举例:
vector<int> vi;
for(int i = 1; i <=5; i++){
vi.push_back(i);
}
vector<int>::iterator it = vi.begin();
注意vi.begin()为取vi的首元素地址,而it指向这个地址
for(int i = 0; i < 5; i++){
printf("%d" ,*(it+1));
}
总结:vi[i] 等价于 (vi.begin()+1)
高级:迭代器实现了两种自加操作,故可改进for循环
for(vector<int>::iterator it = vi.begin(); it != vi.end(); it++){
printf("%d",*it);
}
注意:只有在vector和string中,才允许使用vi.begin()+3这种迭代器加上整数的写法
1.3 vector常用函数解析
0.end() 注意是尾元素地址的下一个地址
1.push_back(x)
2.pop_back()
3.size()
4.clear()
5.insert(it,x)
6.erase(it)
7.erase(vi.begin(),vi.end())
1.4 常见用途
- 存储数据
- 元素不确定个数的场合
- 输出同一行的部分数据,中间用空格隔开——更方便处理最后一个满足条件的数据后不输出额外的空格,先用vector记录所有需要输出的数据,然后一次性输出
- 用邻接表存储图
- 可解决因结点太多而无法使用邻接矩阵的题目、替代指针实现邻接表
2.set
集合,内部自动有序且不含重复元素(默认递增)
#include<set>
using namespace std;
2.1 定义与访问
单独定义一个set:
set<typename> name;
set数组的定义:
set<typename> Arrayname[arraysize];
set容器内元素的访问:
set<int>::iterator it;
枚举set容器:
for(set<int>::iterator it = st.begin(); it != st.end();it++){
printf("%d",*it);
}
注意枚举时不支持 it<st.end()的写法,不支持*(it+1)的访问方式; 访问时只能通过迭代器;
2.2 set常用函数解析
1.insert(x) :将x插入到set容器,O(logN)
2.find(value):返回set中对应值为value的迭代器,O(logN)
譬如:set<int>::iterator it = st.find(2);
3.erase(it):删除单个元素,it为对应元素迭代器,O(1)
4.erase(value):删除对应值,O(logN)
5.erase(first,last):左闭右开,O(Last-first)
6.size():O(1)
7.clear():o(N)
2.3 常见用途
应用:去掉重复元素/元素较大且类型非int不能直接开散列
3.string
#include<string>
using namespace std;
3.1定义与访问
string str;
string str = "abcd";
str[i];
cin>>str;
cout<<str;
printf("%s\n",str.c_str())
string::iterator it = str.begin();
3.2 string常见函数
1.operator+=:拼接
2.compare operator:直接使用=、!=、<、<=、>、>=比较大小,比较规则为字典序
3.length()/size():返回长度,O(1)
4.insert(pos,string):插入字符串,string的开头占据了pos的位置
5.insert(it,it2,it3):将[it2,it3)插入到pos
6.erase(it)
7.erase(first,last)
8.clear()
7.substr(pos,len):返回从pos开始长度为len的子串,O(len)
8.find(str2):当str2是str的子串,返回其第一次出现的位置;若不是,返回string:npos
9.find(str2,pos):从str的pos位置开始匹配str2
10.string::npos :-1或者4294967295
11.replace(pos,len,str2):从pos开始,长度为len的子串替换为str2
12.replace(it1,it2,str2):左闭右开
4.map
映射,将任何基本类型映射到任何基本类型
#include<map>
using namespace std;
4.1 定义与访问
若是字符串到整型的映射,只能使用string不能使用char数组; map会以键从小到大的顺序自动排序(内部是红黑树)
定义:
map<键类型,值类型> name;
map<set<int>, string> mp;
访问使用下标或者迭代器:
mp<char,int> mp;
mp['c'] = 20;
print("%d",mp['c']);
for(map<char,int>::iterator it = mp.begin();it != mp.end(); it++){
printf("%c %d\n",it->first,it->second);
}
4.2 map常用函数
1.find(key):返回指定键的迭代器,O(logN)
2.erase(it):O(!)
3.erase(key):O(logN)
4.erase(first,last)
5.size():O(1)
6.clear():O(N)
7.插入可以使用insert()与pair联用
4.3 常见用途
应用:判断给定数字在一个文件是否出现过? 正常思路:开一个bool型的hashTable[max_size],判断其真值 弊端:数字很大就开不了(几千位) map思路:将这些数字当成字符串,建立string到int的映射
1.字符串与整数之间的映射 2.判断大整数或者其他类型数据是否存在 3.字符串到字符串的映射
5.queue
队列,先进先出
#include<queue>;
using namespace std;
5.1 定义与访问与函数
定义:
queue<typename> name;
访问:
printf("%d%d\n",q.front(),q.back());
常见函数:
1.push(X)
2.front(),back()
3.pop()
4.empty():判断是否为空,返回bool值
5.size()
5.2 常见用途
广度优先搜索 注意使用front()和pop(),先用empty()判断是否非空
6.priority_queue
优先队列,底层用堆实现,队首默认优先级最大 头文件与5相同
6.1 定义、访问与函数
定义
priority_queue<typename> name;
访问:
printf("%d\n",q.top())
常用函数:
1.push(X)
2.top()
3.pop()
4.empty()
5.size()
6.2 优先级设置
默认越大的优先级越大
1.基本数据类型:
priority_queue<int> q;
priority_queue<int, vector<int>, less<int> > q;
第二个参数填写的是承载底层数据结构堆的容器,第三个参数是对第一个参数的比较类
less<typename>表示越大的优先级越大,greater<typename>表示越小优先级越大
2.结构体:重载操作符
struct fruit{
string name;
int price;
friend bool operator < (fruit f1, fruit f2){
return f1.price < f2.price;
以价格高的水果优先级高
}
}
int main(){
priority_queue<fruit> q;
f1.name = "桃子”;
f1.price = ...
...
q.push(f1);
q.push(f2);
...
cout<<q.top().name <<" "<< q.top().price << endl;
return 0;
}
另一种方法:在结构体外定义优先级
struct cmp{
bool operator () (fruit f1, fruit f2){
return f1.price > f2.price;
}
}
priority_queue<fruit,vector<fruit>,cmp> > q;
价格越低的越优先
若结构体数据潘达(出现了字符串或者数组),建议使用引用来提高效率
friend bool operator < (const fruit &f1, const fruit &f2){
return f1.price > f2.price
}
bool operator () (const fruit &f1, const fruit &f2){
return f1.price <f2.price
}
6.3 常见用途
贪心问题,对迪杰斯特拉优化 注意使用top()前判断是否为空
7.stack
栈,先进后出
#include<stack>
using namespace std;
常用函数
1.push(x);
2.top(x)
3.pop()
4.empty()
5.size()
常见用途: 1.模拟实现递归,防止程序对在栈内存的限制导致程序运行出错(一般来说,程序栈内存空间很小)
8.pair
内部由两个元素的结构体
#include<utility>
using namespace std;
或者
#include<map> map的内部实现需要涉及pair
struct pair {
typename1 first;
typename2 second;
};
1.定义
pair<typenmae1,typename2> name;
pair<string,int> p;
pair<sting,int> ("haha", 5);
make_pair("haha",5);
2.访问:按照正常结构体的方式访问
cout<<p.first<<" "<<p.second<<endl;
3.实用函数
比较操作数:先以first大小作为标准,当其相等时判断second的大小;
常见用途: 1.用来代替二元结构体以及构造函数 2.作为map的键值对来进行插入
map<string,int> mp;
mp.insert(make_pair("haha",5));
mp.insert(pair<string,int>("heihei",10));
for(map<string,int>::iterator it = mp.begin()l it !=mp.end(); it++){
cout<<it->first<< " "<<it->second<<endl;
}
9 .algorithm头文件常用函数
9.1 max/min/abs/swap/next_permutation/fill
#include<algorithm>
using namespace std;
1.max(x,y)/min(x,y)/abs(整数)
2.swap(x,y)
3.reverse(it,it2):将数组指针在[it,it2)之间的元素或容器的迭代器在其间的元素进行反转
int a[10] = { 10,11,12,13,14,15};
reverse(a,a+4);
4.next_permutation(first,last):给出一个序列在全排列中的下一个序列
并且在到达全排列的最后一个时会返回false,方便退出循环
int a[10] = {1,2,3};
do{
printf("%d%d%d\n", a[0],a[1],a[2]);
}while(next_permutation(a,a+3));
输出:123 132 213 231 312 321
5.fill(first,last,value):把数组或容器的某一区间赋为一个相同值,
可以是数组类型对应范围中的任意值
9.2 sort(f,l,cmp)
sort(首元素地址(必填),尾元素下一个地址(必填),比较函数(非必填));
默认递增,,char数组排序默认字典序
9.2.1 基本类型
int a[6] = {...};
sort(a, a+4);
编写比较函数cmp
bool cmp(int a ,int b){
return a>b;
}
sort(a,a+4,cmp);
9.2.2 结构体数组
struct node{
int x,y;
}ssd[10];
bool cmp(node a,node b){
return a.x>b.x;
}
bool cmp(node a,node b){
if(a.x != b.x) return a.x> b.x;
else return a.y<b.y;
}
sort(ssd,ssd+3,cmp);
7.2.3容器
只有vector\string\deque可以使用sort,像set、map这种容器用红黑树进行实现,元素本身有序,不允许使用sort排序
1.vector情况:
bool cmp(int a,int b){
return a>b;
}
vector<int> vi;
vi.push_back(3);
vi.push_back(1);
vi.push_back(1);
sort(vi.begin() , vi.end() , cmp);
2.string数组情况
bool cmp(string a,string b){
return a.length() < b.length();
}
string str[3] ={"aaa","bbbb","ccccc"};
sort(str,str+3,cmp);
9.3 lower_bound()与upper_bound()
需要用在有序数组或容器中、
lower_bound(first,last,val):
寻找在该范围内第一个值大于等于val的元素位置,返回指针或迭代器
若没有,返回可以插入的位置
int a[10] = {1,2,2,3,3,3,5,5,5,5};
int* lowerPos = lower_bound(a,a+10,-1);
int* upperPos = upper_bound(a,a+10,-1)
printf("%d,%d\n", lowerPos-a, upperPos-a);
输出:0,0
查下标——令返回值减去数组首地址
|