所有STL函数都要用到
using namespace std;
vector 数组
vector 可以被看成一个“超级数组” ,不会和C语言数组一样被限制长度,它既可以和C语言的数组一样用下标访问,也可以像链表一样动态改变长度。
#include<vector> //头文件
vector<int> arr1(100);
int arr2[100]; //该定义类似C语言数组
vector<int> list;
list.push_back(1);
list.push_back(2);
....
vector 的遍历
vector<int> arr(100);
vector<int> list;
for(int i=0;i<100;i++) //用数组下标的方式,需要定义长度;
{
scanf("%d",&arr[i]);
cout<<arr[i]<<endl;
}
for(int i=0;i<100;i++) //用链表的方式,可以一直加数据;
{
int a;
cin>>a;
list.push_back(a);
printf("%d\n",list[i]);
}
vector 常见操作
list为上面定义的一个vector类型的名字,可变
list.size(); // 数组元素个数 O(1);
list.clear(); // 一键清空数组 O(n);
list.empty(); //数组是否为空 O(1);
list.begin(): //数组首元素的下标 O(1);
list.end(); //数组最后一个元素的下一个元素的下标 O(1);
list.erase(p1); //删除数组某个下标所在位置的数字 O(n);
list.push_back(1); //往数组后面添加元素 O(1);
list.pop_back(); //删除数组最后一个元素 O(1);
vector 在一些元素个数不确定的场合可以很好地节省空间。
string 字符串
字符串string可以看成一个特殊的vector
string和C语言字符串的关系和vector和普通数组的关系一样
#include<cstring> 或 #include<string.h>
string str1="hello";
char str2[]="world";
string str3;
str3.push_back('!');
cout<<str1<<" "<<str2<<str3<<endl;
//hello world!
vector有的操作string基本都有
所有参数为字符串的地方既可以是string也可以是C字符串
str.length(); str.size(); //等同 strlen();
str.insert(1,"aaa"); // 在下标为1处插入一个字符或字符串
str.c_str(); //返回成C语言的字符串,返回后可以用printf输出
//其中第一个str为string类型字符串的名字。
char c[20];
string s="1234";
strcpy(c,s.c_str()); 或者 printf("%s",s.c_str());
str.append(str2); // 把str2拼接到str后面
str.compare(str2); //等同 strcmp(str,str2);
str == str2; //等同 strcmp(str,str2)==0;
str += str2; //等同 str.append(str2);
str += 'a'; //等同 str.push_back('a');
最后三个便是string的特点,也就是这个的方便之处,可以直接用来运算,不用像C语言一样写那么多函数,然后后面的sort快排如果要用来排字符串也只能排string类型的字符串。
algorithm 算法函数
#include<algorithm>
algorithm和之前的两个头文件不同,它没有定义什么新的类型,而是定义了很多算法,极大简化了代码量
sort快速排序
sort(arr,arr+n);
排序开始指针
排序结束指针(最后一个元素的下一个元素的指针)
系统默认从小到大的升序排序法
但是sort可以自定义比较函数
比较函数参数是两个待比较变量,返回值是bool值
比如从大到小的降序排序函数可以这样写
bool cmp(int a,int b)
{
return a>b;
}
sort(arr,arr+n,cmp);
自己定义的结构体一定要写比较函数
如下面,比较函数是先比较x坐标,在x坐标相同的情况下比较y坐标
struct point
{
int x,y;
};
point arr[10000]; //c++可以直接用这个结构体类型名
//不用像C语言一样要加 typedef 去换一个结构体名
bool cmp(point a,poinrt b)
{
if(a.x!=b.x)
return a.x < b.x;
return a,y < b.y;
}
sort(arr,arr+10,cmp);
next_permutation函数
next_permutation(start,end)
prev_permutation(start,end)
两个函数一样,区别在于前者求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列
next_permutation(arr,arr+n)是对数组arr中的前n个元素进行全排列,同时改变arr数组的值。
在使用前要对数组升序排序,否则只能找出该排序后的全排列数
int num[3]={
1,2,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
1 2 3
1 3 2
2 1 3
3 1 2
3 2 1
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+2));
1 2 3
2 1 3
int num[3]={
2,1,3};
do
{
cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;
}while(next_permutation(num,num+3));
2 3 1
3 1 2
3 2 1
其他algorithm函数
min(a,b); //返回较小值
max(a,b); //返回较大值
nth_element(a,a+x,a+n);
将数组中第x小的数放到第x个位置
如a[9]={
4,7,6,9,1,8,2,3,5};
nth_element(a,a+2,a+9)
将下标为2,也就是排序后a[2]位置的数求出来,但是对其他元素没有排序
当然和sort一样可以自定义排序的比较函数
swap(a,b); //交换两个数
reverse(a,a+n); //反转数组
unique(a,a+n); //对数组进行去重
unique需要在排序好后使用,放回值是最后一个元素的地址
int l=unique(a,a+n)-a; //l即为去重后数组的个数
lower_bound(a,a+n,x); //返回第一个不小于x的数的地址;
upper_bound(a,a+n,x); //返回第一个大于x的数的地址;
a[5]={
1,2,2,3,4};
int l=lower_bound(a,a+5,2)-a;
int d=upper_bound(a,a+5,2)-a;
// l=1; d=3;
stack 栈
#include<strack>
strack<int> sta;
sta.push(1); //入栈
int a=sta.top(); //取栈顶元素
sta.pop(); //出栈
sta.empty(); //判空
sta.size(); //栈内元素个数
queue 队列
包含队列 (queue) 和优先队列 (priority_queue) 两种数据结构
两者用法和stack完全相同
#include<queue>
queue<int> que;
que.push(1); //入队
int a=que.front(); //取队头元素,这里不是top,而是front
//优先级队列便还是top
que.pop();
que.empty();
que,size();
map 映射
map包含的第一个数据结构是pair,它可以由任意两种类型构成,当你偷懒不想写结构体,又要用到两个相关联的变量时可以,用pair,pair自带比较函数,默认先比第一个元素再比第二个元素
#include<map>
pair<string,int> p1("james","18");
pair<int,double> p2;
p2.first = 1;
p2.second = 2.5;
pair<int,int> p3;
p3=make_pair(0,0);
map的第二个数据结构就是map
map可以看成一个超级数组,你可以吧字符串或者其他类型当成数组的下标。
map<string,int> stu;
stu["小明“]=170;
stu["小红“]=150;
以上的头文件都不需要记忆,只要
#include<bits/stdc++.h>
就能一键包含所有头文件(Visual Studio 除外)
学习STL的正确姿势
1、http://www.cplusplus.com/reference/认真查看STL用法
2、利用好的编译器的STL自动补全功能,由函数名知道函数的用法,并在实践中得出真知