C++标准模板库(STL)——queue、priority_queue、stack、pair、algorithm头文件下的常用函数


一、queue

queue为队列,具有先进先出的特性。使用queue,需要添加#include< queue >和using namespace std;

1、queue的定义:

queue<typename> name;//typename可以是任意基本数据类型或容器

queue元素的访问:
由于queue本身就是一种先进先出的限制性数据结构,所以STL只能够提供front()来访问队首元素,用back()来访问队尾元素

#include<queue>
#include<stdio.h>
using namespace std;

int main(){
    queue<int> q;
    for(int i = 1 ; i <= 5 ; i++)
        q.push(i);
    printf("%d",q.front());//1
    return 0;
}

3、push()
push(x):将x入队,插入到队尾的位置

4、pop()
令队首元素出队

#include<queue>
#include<stdio.h>
using namespace std;

int main(){
    queue<int> q;
    for(int i = 1 ; i <= 5 ; i++)
        q.push(i);
    for(int i = 1 ; i <= 3 ; i++)
        q.pop();
    printf("%d",q.front());//4
    return 0;
}

5、empty()
检测队列是否为空,如果是则返回true,不是则返回false

6、size()
返回队列中元素的个数

注意:在使用front()和pop()函数之前,必须使用empty()函数判断队列是否为空,否则可能出现错误

二、priority_queue

优先队列,底层是用堆来实现的,在优先队列中,队首元素一定是当前队列中优先级最高的那一个。使用的时候要添加#include< queue >以及using namespace std;

1、priority_queue的定义:

priority_queue<typename> name;

2、priority_queue容器内元素的访问:
与queue不同的是,优先队列没有front()和back()函数,只能够通过top()函数来访问队首元素

#include<queue>
#include<stdio.h>
using namespace std;

int main(){
    priority_queue<int> q;
    q.push(3);
    q.push(4);
    q.push(1);
    printf("%d",q.top());//4
    return 0;
}

3、push():
push(x):令x入队

4、top():
可以获得队首元素,实现容器内元素的访问

5、pop():
令队首元素出队

6、empty():
检测队列是否为空,若为空则返回true,否则返回false

7、size()
返回优先队列中元素的个数

8、元素优先级设置
(1)基本数据类型的优先级设置
以int类型为例,下面两种定义是等价的:

priority_queue<int> q;

priority_queue<int,vector<int>,less<int> > q;

第二种方式中vector< int >是来承载底层数据结构堆得容器,而less< int >则是对第一个参数的比较类,less< int >表示数字大的优先级越大,greater< int >表示数字小的优先级越大

#include<queue>
#include<stdio.h>
using namespace std;

int main(){
    priority_queue<int,vector<int>,greater<int> > q;//数字小的优先级越大
    q.push(3);
    q.push(4);
    q.push(1);
    printf("%d",q.top());//1
    return 0;
}

(2)结构体优先级设置
如用水果的名称和价格建立一个结构体,现在希望对水果价格高的优先极高,就需要重载“<”小于号,重载大于号会编译错误。

struct fruit{
    string name;
    int price;
    friend bool operator < (fruit f1 , fruit f2){
        return f1.price < f2.price;
    }
};

注意:优先队列中的这个函数与sort中的cmp函数的效果是相反的,设置f1.price<f2.price是从小到大排列, 但是在优先队列中的效果是价格高的优先级高

示例:想以价格低的水果优先级高

#include<queue>
#include<string>
#include<iostream>
using namespace std;

struct fruit{
    string name;
    int price;
    friend bool operator < (fruit f1 , fruit f2){
        return f1.price > f2.price;
    }
}f1,f2,f3;

int main(){
    priority_queue<fruit> q;
    f1.name = "桃子";
    f1.price = 3;
    f2.name = "梨子";
    f2.price = 4;
    f3.name = "苹果";
    f3.price = 1;
    q.push(f1);
    q.push(f2);
    q.push(f3);
    cout<<q.top().name<<" "<<q.top().price<<endl;
    return 0;
}

在这里插入图片描述

**常见用途:**可以解决一些贪心问题,也可以对迪杰斯特拉算法进行优化

三、stack

栈:后进先出的容器。想要使用栈,必须添加#include< stack >并加上using namespace std;

1、stack的定义:

stack<typename> name;

2、元素的访问:
stack中只能通过top()来访问栈顶元素

3、push():
push(x):将x入栈

4、pop()
pop()用以弹出栈顶元素

#include<stdio.h>
#include<stack>
using namespace std;

int main(){
    stack<int> s;
    for(int i = 1 ; i <= 5 ; i++)
        s.push(i);
    for(int i = 1 ; i <=3 ; i++)
        s.pop();
    printf("%d",s.top());//2
    return 0;
}

5、empty():
检测stack是否为空,如果为空返回true,不为空则返回false

6、size():
返回stack内的元素的个数

四、pair

当想要将两个元素绑在一起作为一个合成元素、又不想定义结构体时,可以使用pair。也就是说,pair实际上可以看做一个内部有两个元素的结构体。想使用pair,要添加#include< utility >以及using namespace std。

1、pair的定义:

pair<typename1,typename2> name;

如:
pair<string,int> p;

也可以定义的时候进行初始化:
pair<string,int> p("haha",5);

2、元素的访问:
pair中只有两个元素,分别为first和second

#include<utility>
#include<iostream>
#include<string>
using namespace std;

int main(){
    pair<string,int> p;
    p.first="haha";
    p.second=5;
    cout<<p.first<<" "<<p.second<<endl;
    p = make_pair("xixi",55);
    cout<<p.first<<" "<<p.second<<endl;
    p = pair<string,int>("heihie",555);
    cout<<p.first<<" "<<p.second<<endl;
    return 0;
}

3、比较:
两个pair类型可以通过==、!=、<、<=、>、>=比较大小,规则是先以first的大小作为标准,只有当first相等时再去判别second的大小

常见用途:

  • 用来代替二元结构体及其构造函数
  • 作为map的键值对来进行插入
#include<utility>
#include<iostream>
#include<string>
#include<map>
using namespace std;

int main(){
   map<string,int> mp;
   mp.insert(make_pair("heihei",5));
   mp.insert(pair<string,int>("haha",10));
   for(map<string,int>::iterator it = mp.begin();it!=mp.end();it++){
    cout<<it->first<<" "<<it->second<<endl;
   }
   return 0;
}

在这里插入图片描述

五、algorithm头文件下的常用函数

1、max()、min()、abs():

max(x,y)、min(x,y)返回x、y中的最大值和最小值。且参数必须是两个,如果有三个参数,可以使用max(x,max(y,z))的写法。
abs(x)返回x的绝对值。x必须是整数,如果是浮点数请用math头文件下的fabs

2、swap():

swap(x,y)用来交换x、y的值

3、reverse():

reverse(it,it2)可以将数组指针在[it,it2)之间的元素或容器的迭代器在[it,it2)范围内的元素进行反转

#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;

int main(){
    string str = "abcdefghi";
    reverse(str.begin()+2,str.begin()+6);
    for(int i = 0 ; i < str.length() ; i++)
        printf("%c",str[i]);//abfedcghi
    return 0;
}

4、next_permutation():

给出一个序列在全排列中的下一个序列。
例如:当n=3时的全排列

123
132
213
231
312
321
#include<stdio.h>
#include<algorithm>
using namespace std;

int main(){
    int a[10]={1,2,3};
    do{
        printf("%d%d%d\n",a[0],a[1],a[2]);
    }while(next_permutation(a,a+3));
    return 0;
}

在这里插入图片描述
在到达全排列的最后一个时next_permutation会返回false,这样会方便退出循环

5、fill():

可以将数组或容器中的某一段区间赋值为某个相同的值,与memset不同,这里的赋值可以是数组类型对应范围内的任何值

#include<stdio.h>
#include<algorithm>
using namespace std;

int main(){
    int a[5]={1,2,3,4,5};
    fill(a,a+5,233);
    for(int i = 0 ; i < 5 ; i++)
        printf("%d ",a[i]);
    return 0;
}

6、sort():

是用来排序的函数:

sort(首元素地址,尾元素地址的下一个地址,比较函数)

比较函数可以根据需要填写,如果不写,默认对前面给出的区间进行递增排序

例如:对于char型数组从大到小排序(按字典序)

#include<stdio.h>
#include<algorithm>
using namespace std;

bool cmp(char a , char b){
    return a>b;
}

int main(){
    char a[] = {'T','W','A','K'};
    sort(a,a+4,cmp);;
    for(int i = 0 ; i < 4 ; i++)
        printf("%c",a[i]);//WTKA
    return 0;
}

如:对于结构体的排序定义,x不等时按照x从大到小排序,x相等时按照y从小到大排序

#include<stdio.h>
#include<algorithm>
using namespace std;

struct node{
    int x,y;
}ssd[10];

bool cmp(node a , node b){
    if(a.x != b.x)
        return a.x > b.x;
    else
        return a.y < b.y;
}

int main(){
    ssd[0].x = 2;
    ssd[0].y = 2;
    ssd[1].x = 1;
    ssd[1].y = 3;
    ssd[2].x = 2;
    ssd[2].y = 1;
    sort(ssd,ssd+3,cmp);
    for(int i = 0 ; i < 3 ; i++)
        printf("%d %d\n",ssd[i].x,ssd[i].y);
    return 0;
}
// 2 1
// 2 2
// 1 3

容器的排序:在STL中,只有vector、string、deque时可以使用sort的,因为set和map这种容器本身就有序

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;

bool cmp(int a , int b){
    return a>b;
}

int main(){
    vector<int> vi;
    vi.push_back(3);
    vi.push_back(1);
    vi.push_back(2);
    sort(vi.begin(),vi.end(),cmp);
    for(int i = 0 ; i < 3 ; i++)
        printf("%d ",vi[i]);
    return 0;
}

7、lower_bound()、upper_bound()

需要用在一个有序数组或者容器中。
lower_bound(first,last,val)寻找在数组或容器的[first,last)范围内第一个值大于等于val的元素的位置,如果是数组则返回该位置的指针,如果是容器,则返回该位置的迭代器
upper_bound(first,last,val)寻找在数组或容器的[first,last)范围内第一个值大于val的元素的位置,如果是数组则返回该位置的指针,如果是容器,则返回该位置的迭代器
如果没有寻找到,则返回可以插入该元素的位置的指针或者迭代器

#include<stdio.h>
#include<algorithm>
using namespace std;

int main(){
    int a[10] = {1,2,2,3,3,3,5,5,5,5};
    //寻找-1
    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

    //寻找3
    lowerPos = lower_bound(a,a+10,3);
    upperPos = upper_bound(a,a+10,3);
    printf("%d,%d\n",lowerPos-a,upperPos-a);//3,6

    return 0
}

猜你喜欢

转载自blog.csdn.net/weixin_46025531/article/details/122799564