文章目录
- STL专题之set集合
- STL专题之stack栈
- STL专题之sort排序
- STL专题之map映射
- STL专题之queue队列
- STL专题之vector向量
- STL专题之deque双向队列
- STL专题之Binary search二分
- STL专题之priority_queue队列
- STL专题之set集合string字符串
- STL专题之next_permutation全排列
- STL专题之nth_element找到第k个数
- STL专题之bitset位运算+acm常用定义
STL专题之set集合
头文件#include
set容器中的元素不能重复(自带去重功能),并且set容器能将元素进行自动排序.set可以用来去重和排序.set为关联容器,使用迭代器时只支持it++操作.
insert()函数:
int a[3]={
3,4,5};
set<int>s;
s.insert(1);
s.insert(2);
s.insert(2);//set具有去重功能,不会重复插入
s.insert(a,a+3);
for(set<int>::iterator it=s.begin();it!=s.end();it++)//set的遍历
cout<<*it<<" ";//1 2 3 4 5
for(set<int>::reverse_iterator it=s.rbegin();it!=s.rend();it++)//反序遍历
cout<<*it<<" ";//5 4 3 2 1
cout<<endl;
erase()函数:删除错误的值不会检查
//以上述插入代码为例
s.erase(1);
for(set<int>::iterator it=s.begin();it!=s.end();it++)
cout<<*it<<" ";//2 3 4 5
cout<<endl;
s.erase(s.begin());
for(set<int>::iterator it=s.begin();it!=s.end();it++)
cout<<*it<<" ";//3 4 5
cout<<endl;
s.erase(s.begin(),s.end());
if(s.size()) cout<<"yes"<<endl;
else cout<<"no"<<endl;//表示set中没有元素
find()函数:返回的是某个元素迭代器的位置.如果该元素不存在则返回end().
set的排序(默认升序)
1.自定义比较类
//降序排序
struct cmp{
bool operator()(int a,int b){
return a>b;
}
};
int main() {
int a[3]={
3,4,5};
set<int,cmp>s;
s.insert(1);
s.insert(2);
s.insert(2);//set具有去重功能,不会重复插入
s.insert(a,a+3);
for(set<int>::iterator it=s.begin();it!=s.end();it++)
cout<<*it<<" ";//5 4 3 2 1
cout<<endl;
return 0;
}
2.重载运算符
//方法一
struct Student{
int age;
char name[100];
}student[Max_n];
bool operator <(const Student &a,const Student &b){
return a.age<b.age;//对年龄去重并且降序
}
int main(){
set<Student>s;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s %d",student[i].name,&student[i].age);
s.insert(student[i]);
}
for(set<Student>::iterator it=s.begin();it!=s.end();it++)
printf("%s %d\n",(*it).name,(*it).age);
return 0;
}
//方法二(set具有去重功能)
struct Student{
int age;
char name[100];
bool operator <(const Student &a)const {
return age<a.age;//对年龄去重
}
}student[Max_n];
int main(){
set<Student>s;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s %d",student[i].name,&student[i].age);
s.insert(student[i]);
}
for(set<Student>::iterator it=s.begin();it!=s.end();it++)
printf("%s %d\n",(*it).name,(*it).age);
return 0;
}
STL专题之stack栈
头文件#include
stack是一种容器适配器,用于先进后出的操作,元素的插入和删除操作只能在容器的尾部进行.
STL专题之sort排序
头文件#include
sort的应用
int a[5]={
5,4,3,2,1};
sort(a,a+5);//从小到大排序
sort(a,a+5,greater<int>());//从大到小排序
for(int i=0;i<5;i++)
printf("%d ",a[i]);
自定义排序
1.自定义比较函数
bool cmp(int a,int b){
return a>b;
}
sort(a,a+5,cmp);
2.重载运算符
//方法一
struct Student{
int age;
char name[100];
}student[Max_n];
bool operator <(const Student &a,const Student &b){
if(a.age==b.age)
return a.name<b.name;//年龄相同按照名字从小到大排序
return a.age<b.age;//按照年龄从小到大排序
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s %d",student[i].name,&student[i].age);
sort(student+1,student+n+1);
for(int i=1;i<=n;i++)
printf("%s %d\n",student[i].name,student[i].age);
return 0;
}
//方法二
struct Student{
int age;
char name[100];
bool operator <(const Student &a)const{
if(a.age==age)
return name<a.name;//年龄相同按照名字从小到大排序
return age<a.age;//按照年龄从小到大排序
}
}student[Max_n];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s %d",student[i].name,&student[i].age);
sort(student+1,student+n+1);
for(int i=1;i<=n;i++)
printf("%s %d\n",student[i].name,student[i].age);
return 0;
}
3.声明比较类
struct Student{
int age;
char name[100];
}student[Max_n];
struct cmp{
bool operator()(const Student &a,const Student &b){
if(a.age==b.age)
return a.name<b.name;//年龄相同按照名字从小到大排序
return a.age<b.age;//按照年龄从小到大排序
}
};
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%s %d",student[i].name,&student[i].age);
sort(student+1,student+n+1,cmp());
for(int i=1;i<=n;i++)
printf("%s %d\n",student[i].name,student[i].age);
return 0;
}
STL专题之map映射
头文件#include
map是一种映射,它可以建立key到value的一对一关系,有key映射到value,我的理解差不多就相当于一个函数关系,一个x可以对应多个y,但是一个y不能对应多个x(用下面程序来解释我对于这段话的解释.).map可以对数据进行自动排序.map可以快速查找和删除.map可以用来去重,排序和计数.
map<char,int>m;
m['a']=1;
m['b']=1;
m['a']=2;
for(map<char,int>::iterator it=m.begin();it!=m.end();it++)
cout<<it->first<<"->"<<it->second<<endl;//这里需要注意map与vector访问元素的不同
常用方法
insert()除了用上面的方法插入数据以外我们还可以用insert()这个函数.
//insert()插入元素
map<char,int>m;
m.insert(make_pair('a',1));
m.insert(make_pair('b',1));
m.insert(make_pair('a',2));//注意这里不会被覆盖,如果再次插入已经存在的元素,迭代器会指向原来的位置
for(map<char,int>::iterator it=m.begin();it!=m.end();it++){
//遍历map可以使用迭代器或者数组的方式
cout<<it->first<<"->"<<it->second<<endl;//这里需要注意map与vector访问元素的不同
}
for(auto x:m){
//set,vector都可以
cout<<x.first<<"->"<<x.second<<endl;
}
find(key)返回某个key的迭代器.如果不存在这个key就返回end()函数的迭代器(也就是指向second时值为0).
map的三个应用
去重:假设我们有一个key值出现了很多次,而且我们只需要一个的时候,此时我们就可以使用map来去重.(当然在后面我还会说到set应该是要比这个方便很多.)
排序:原本默认按照key值的字典序进行排序.,如果我们需要的方式进行排序,此时我们就可以自定义类来进行排序.
计数:只要我们输入一个key值就进行m[key]++操作,这样一来我们就可以统计key出现了多少次.
//按照key值默认字典序排序(升序)
map<string,int>m;
m["sdft"]=20;
m["sdfsdfs"]=26;
m["dfgfdg"]=30;
for(map<string,int>::iterator it=m.begin();it!=m.end();it++)
cout<<it->first<<" "<<it->second<<endl;
//按照key值降序输出
map<string,int,greater<string> >m;
m["sdft"]=20;
m["sdfsdfs"]=26;
m["dfgfdg"]=30;
for(map<string,int>::iterator it=m.begin();it!=m.end();it++)
cout<<it->first<<" "<<it->second<<endl;
//自定义排序方式(按照字符串长度升序)
struct cmp{
bool operator ()(string a,string b){
return a.length()<b.length();
}
};
int main(){
map<string,int,cmp>m;
m["sdft"]=20;
m["sdfsdfs"]=26;
m["dfgfdg"]=30;
for(map<string,int>::iterator it=m.begin();it!=m.end();it++)
cout<<it->first<<" "<<it->second<<endl;
return 0;
}
STL专题之queue队列
头文件#include
queue是一种容器适配器,用于先进先出的操作,元素的插入在容器的尾部进行,删除操做在容器的头部进行.
queue<int>q;
q.push(1);
q.push(2);
q.push(3);
q.push(1);
while(q.size()){
cout<<q.front()<<" ";
q.pop();//1 2 3 1
}
STL专题之vector向量
头文件#include
vector是可以变换大小的数组的一种容器,vector用连续的存储空间来存储数据,可以用类似于数组的方式下标直接访问其中的元素.存储的元素超过与分配的空间时,与string类似,它会重新分配空间来存放数据.
//下标访问vector
for(int i=1;i<=n;i++){
cin>>a;
s.push_back(a);
}
int len=s.size();
for(int i=0;i<len;i++)
cout<<s[i]<<" ";
常用函数
使用clear()函数的时候需要注意,如果题目需要多组输入的时候,我们在输出后一定要把数据clear,不然在下一组测试的时候数据依然会在vector中,进而影响后面的答案.
reverse(a.begin(),a.end())对字符串进行反转可以快速判断一个字符串是否是回文的.
string a;
vector<string>s;
for(int i=1;i<=n;i++){
cin>>a;
string b=a;
reverse(b.begin(),b.end());//对字符串进行翻转
if(a==b) s.push_back(a);//如果回文放进vector
}
for(vector<string>::iterator it=s.begin();it!=s.end();it++)
cout<<*it<<" ";
迭代器
vector
这条语句表示我们声明了一个it的变量,它的类型是vector
定义的iterator类型.我们可以用这个迭代器来遍历vector数组.it1-it2 返回it1和it2在容器内的差值.
//遍历数组
for(vector<string>::iterator it=s.begin();it!=s.end();it++)
cout<<*it<<" ";
cout<<endl<<s.end()-s.begin()<<endl;//返回的是差值,不是迭代器
声明与初始化
vector<int>v;//声明一个int型的数组(也叫向量)
vertor<int>v(5);//声明一个大小为5的int型数组
vector<int>v(10,1);//声明一个大小为10并且值都是1的int型数组
vector<vector<int> >v;//声明一个int型的二维数组
STL专题之deque双向队列
与队列很像,这里只列出常用函数.
deque<int> d;
d.push_back(5); // [5]
d.push_back(2); // [5,2]
d.push_front(3); // [3,5,2]
d.pop_back(); // [3,5]
d.pop_front(); // [5]
STL专题之Binary search二分
int main(){
int a[6]={
1,2,2,2,2,3};//从小到大排序
//返回第一个>x的数下标,不存在返回n.
cout<<upper_bound(a,a+6,2)-a<<endl;//5
//返回第一个>=x的数的下标,不存在返回n.
cout<<lower_bound(a,a+6,2)-a<<endl;//1
int b[6]={
3,2,2,2,2,1};//从大到小排序
//返回第一个<=x的数,不存在返回n.
cout<<lower_bound(b,b+6,2,greater<int>())-b<<endl;//1
//返回第一个
cout<<upper_bound(b,b+6,2,greater<int>())-b<<endl;//5
auto r=equal_range(a,a+6,2);
cout<<r.second-a<<" "<<r.first-a<<endl;
//r.second-a 第一个>x的数下标,不存在返回n.
//r.first-a 第一个>=x的数的下标,不存在返回n.
return 0;
}
STL专题之priority_queue队列
头文件#include
priority_queue用于先进先出的操作,元素的插入在容器的尾部进行,删除操做在容器的头部进行.它会对插入的数据进行排序
//大的在队列的最前面
priority_queue<int>q;
q.push(1);
q.push(2);
q.push(3);
q.push(1);
while(q.size()){
cout<<q.top()<<" ";
q.pop();//3 2 1 1
}
//小的在队列的最前面
priority_queue<int,vector<int>,greater<int> >q;
q.push(1);
q.push(2);
q.push(3);
q.push(1);
while(q.size()){
cout<<q.top()<<" ";
q.pop();//3 2 1 1
}
//重载运算符排序(通常与贪心一起用)(有结构体时必须重载运算符)
struct Student{
int age;
int grade;
bool operator <(const Student &a)const {
if(grade==a.grade)
return age<a.age;//成绩相同按照年龄排序,大的在队列最前面
return grade<a.grade;//大的在队列最前面
}
}student[Max_n];
int main(){
priority_queue<Student>q;
for(int i=1;i<=3;i++) {
cin >> student[i].age >> student[i].grade;
q.push(student[i]);
}
while(q.size()){
cout<<q.top().age<<" "<<q.top().grade<<endl;
q.pop();
}
return 0;
}
STL专题之set集合string字符串
string a = "hatti";
string b = a+a;
cout << b << "\n"; // hattihatti
b[5] = ’v’;
cout << b << "\n"; // hattivatti
string c = b.substr(3,4);
cout << c << "\n"; // tiva
STL专题之next_permutation全排列
int a[6]={
1,2,3,4,5,6};//按照字典序输出123456的第四个排列
for(int i=1;i<4;i++)
next_permutation(a,a+6);
for(int i=0;i<6;i++)
printf("%d ",a[i]);
string s="123";
do{
cout<<s<<endl;//输出所有全排列
}while(next_permutation(s.begin(),s.end()));
int main(){
for(int i=1;i<=3;i++)
v.push_back(i);
do{
for(auto i:v)
cout<<i<<" ";
cout<<endl;
for(auto it=v.begin();it!=v.end();it++)
cout<<*it<<" ";
cout<<endl;
for(vi::iterator it=v.begin();it!=v.end();it++)
cout<<*it<<" ";
cout<<endl;
}while(next_permutation(v.begin(),v.end()));
return 0;
}
STL专题之nth_element找到第k个数
bool cmp(int a,int b){
return a>b;
}
int main(){
int a[7]={
0,1,3,4,6,7,8};
nth_element(a+1,a+2,a+7,cmp);//找到第二大的数
printf("%d\n",a[2]);//7
nth_element(a+1,a+2,a+7);//找到第二小的数
printf("%d\n",a[2]);//3
return 0;
}
STL专题之bitset位运算+acm常用定义
#include
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define SQ(a) (a)*(a)
typedef vector<int> vi;
typedef pair<int,int>pi;
typedef long long LL;
const int Max_n=105;
int main(){
bitset<10>s;
s[1]=1;
s[3]=1;
cout<<s[0]<<" "<<s[1]<<" "<<s[2]<<" "<<s[3]<<" "<<s[4]<<" "<<s[5]
<<" "<<s[6]<<" "<<s[7]<<" "<<s[8]<<" "<<s[9]<<endl;
bitset<4>a(string("1101"));
cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl;//1 0 1 1
cout<<a.count()<<endl;
bitset<10>x(string("0010110110"));
bitset<10>y(string("1011011000"));
cout<<(x&y)<<endl;
cout<<(x|y)<<endl;
cout<<(x^y)<<endl;
return 0;
}