C++ STL常用操作

本文详细介绍了C++ STL中的vector、pair、stack、queue、algorithm等组件的使用,包括初始化、操作、算法等内容。重点讲解了vector的初始化、元素访问,pair的创建与操作,stack和queue的基本操作,以及algorithm中的各种操作如排序、查找、最大最小值等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

目录

一、vector

1.vector 的初始化

2.vector对象的常用操作

3.顺序访问vector方式

4.常用算法

二、pair

1、创建和初始化

2、pair对象操作

三、stack

定义stack对象:

stack的基本操作:

四、queue

定义queue对象

queue的基本操作

优先队列priority_queue

五、algorithm

不修改内容操作

修改内容操作

排序操作

查找操作

最大最小操作

划分操作

集合操作

堆操作

其他

结构体定义

操作符重载

模板

 


STL是Standard Template Library的简称,中文名标准模板库,惠普实验室开发的一系列软件的统称。在C++标准中,STL被组织为下面的13个头文件:<algorithm>、<deque>、<functional>、<iterator>、<array>、<vector>、<list>、<forward_list>、<map>、<unordered_map>、<memory>、<numeric>、<queue>、<set>、<unordered_set>、<stack>和<utility>。

一、vector

vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员,使用它时需要包含头文件:

#include<vector>;

1.vector 的初始化

vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
int b[7]={1,2,3,4,5,9,8};
vector<int> a(b,b+7); //从数组中获得初值


2.vector对象的常用操作

a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
a.pop_back(); //删除a向量的最后一个元素
a[i]; //返回a的第i个元素,当且仅当a[i]存在
a.back(); //返回a的最后一个元素
a.front(); //返回a的第一个元素
a.clear(); //清空a中的元素
a.empty(); //判断a是否为空,空则返回ture,不空则返回false
a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
a.assign(4,2); //是a只含4个元素,且每个元素为2
a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)
a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8,插入元素后为1,4,5,9,2,3,4,5,9,8
a.size(); //返回a中元素的个数;
a.capacity(); //返回a在内存中总共可以容纳的元素个数
a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能) 
a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<

3.顺序访问vector方式

(1)向向量a中添加元素
1、

vector<int> a;
for(int i=0;i<10;i++)
a.push_back(i);

 

2、也可以从数组中选择元素向向量中添加

int a[6]={1,2,3,4,5,6};
vector<int> b;
for(int i=1;i<=4;i++)
b.push_back(a[i]);

 

 

3、也可以从现有向量中选择元素向向量中添加

int a[6]={1,2,3,4,5,6};
vector<int> b;
vector<int> c(a,a+4);
for(vector<int>::iterator it=c.begin();it<c.end();it++)
b.push_back(*it);

 

4、也可以从文件中读取元素向向量中添加

ifstream in("data.txt");
vector<int> a;
for(int i; in>>i)
    a.push_back(i);

 

5、【误区】

vector<int> a;
for(int i=0;i<10;i++)
    a[i]=i;

//下标只能用于获取已存在的元素,而现在的a[i]还是空的对象

 

(2)从向量中读取元素
1、通过下标方式读取

int a[6]={1,2,3,4,5,6};
vector<int> b(a,a+4);
for(int i=0;i<=b.size()-1;i++)
    cout<<b[i]<<" ";

 

2、通过遍历器方式读取

int a[6]={1,2,3,4,5,6};
vector<int> b(a,a+4);
for(vector<int>::iterator it=b.begin();it!=b.end();it++)
    cout<<*it<<" ";

 

4.常用算法

使用时需要包含头文件:

#include<algorithm>
sort(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列
reverse(a.begin(),a.end()); //对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
copy(a.begin(),a.end(),b.begin()+1); //把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开始复制,覆盖掉原有元素
find(a.begin(),a.end(),10); //在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置

二、pair

使用pair类型需包含头文件<utility>,定义如下:

类模板:template<class T1,class T2> struct pair

参数:T1是第一个值得数据类型,T2是第二个值的数据类型。

1、创建和初始化

//创建
pair<string, int> word_count;     // 创建一个空对象 word_count, 两个元素类型分别是string和int类型
pair<string, vector<int> > line;  // 创建一个空对象line,两个元素类型分别是string和vector类型

//定义时初始化
pair<string, string> author("James","Joy");    // 创建一个author对象,两个元素类型分别为string类型,并默认初始值为James和Joy。
pair<string, int> name_age("Tom", "18");
pair<string, int> name_age2(name_age);    // 拷贝构造初始化

//typedef简化
typedef pair<string,string> Author;
Author proust("March","Proust");

2、pair对象操作

pair<int ,double> p1; 
p1.first = 1; 
p1.second = 2.5; 
cout<<p1.first<<' '<<p1.second<<endl; 
//输出结果:1 2.5

利用make_pair函数生成pair对象

 pair<int, double> p1;
 p1 = make_pair(1, 1.2);
 
cout << p1.first << p1.second << endl;

pair类型数据利用sort函数排序时默认根据first的数值排序。

三、stack

c++stack(堆栈)是一个容器的改编,它实现了一个先进后出的数据结构(FILO)。

stack 模板类的定义在<stack>头文件中。stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要的,在不指定容器类型时,默认的容器类型为deque。

定义stack对象:

stack<int>s1;

stack<string>s2;

stack的基本操作:

1.入栈:s.push(x);

2.出栈:s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。

3.访问栈顶元素:s.top();

4.判断栈空:s.empty().当栈空时返回true。

5.访问栈中的元素个数:s.size();

四、queue

queue类是C++提供的一个队列的功能的容器适配器,实现了一个FIFO(先入先出)的数据结构。queue模版类的定义在<queue>头文件中。

queue与stack模版非常类似,queue模版也需要定义两个模版参数,一个是元素类型,一个是容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型。

定义queue对象

queue<int>q1;
queue<double>q2;

queue的基本操作

1.入队:如q.push(x):将x元素接到队列的末端;

2.出队:如q.pop() ,弹出队列的第一个元素,并不会返回元素的值;

3.访问队首元素:如q.front();

4.访问队尾元素,如q.back();

5.访问队列中的元素个数,如q.size();

6.判断队列空:q.empty(),当队列为空时返回true。

优先队列priority_queue

在<queue>头文件中,还定义了一个非常有用的模版类priority_queue(优先队列),优先队列与队列的差别在于优先队列不是按照入队的顺序出队,而是按照队列中元素的优先权顺序出队(默认为大者优先即大顶堆,也可以通过指定算子来指定自己的优先顺序)。

priority_queue模版类有三个模版参数,元素类型,容器类型,比较算子。其中后两个都可以省略,默认容器为vector,默认算子为less,即小的往前排,大的往后排(出队时序列尾的元素出队)。

定义priority_queue对象的示例代码如下:

priority_queue<int >q1;

priority_queue<pair<int,int> >q2;

priority_queue<int,vector<int>,greater<int> >q3;//定义小的先出队

priority_queue的基本操作均与queue相同。

定义比较算子的方法:重载比较运算符。优先队列试图将两个元素x 和y 代入比较运算符(对less 算子,调用x<y,对greater 算子,调用x>y),若结果为真,则x 排在y 前面,y 将先于x 出队,反之,则将y 排在x 前面,x 将先出队。

五、algorithm

<algorithm>头文件是C++的标准模版库中最重要的头文件之一,提供了大量基于迭代器的非成员模板函数。

不修改内容操作

 for_each(Iterator begin,Iterator end,Function fn)对容器指定范围中的每个元素调用指定函数

 find(begin,end,const T& val)返回指定范围内第一个值等于val的元素的迭代器,若没有该元素则返回end

 find_if(begin,end,pred)返回指定范围内第一个值满足给定条件pred的元素的迭代器,若没有该元素则返回end

 count(begin,end,const T& val)返回指定范围内值等于给定值的元素的个数

 count_if(begin,end,pred)返回指定范围内满足给定条件的元素的个数

 search(begin1,end1,begin2,end2)返回范围[begin1,last1)中第一个与范围[begin2,end)等价的子范围首元素迭代器

修改内容操作

unique(begin,end,pred) 移去指定范围中的所有连续重复元素,仅仅留下每组等值元素中的第一个元素,返回值是去重之后范围的尾地址 ,m=unique(a,a+n)-a,m即为去重后元素个数。

copy(begin,end,result) 将[begin,endl)范围内元素复制到result开始的范围中并返回其尾迭代器。

swap(a,b)交换对象的值

move(begin,end,result) 将[begin,endl)范围内元素移动到result开始的范围中并返回其尾迭代器。

remove(begin,end,val) 将[begin,endl)范围内值等于val的元素移动到result开始的范围中并返回其尾迭代器。

replace(begin,end,old,new)将[begin,end)范围内值等于old的元素赋值为new。

reverse(begin,end)将指定范围内元素反=反转排序。

rotate(begin,middle,end) 循环移动范围[begin,end)中的元素,使middle成为新的首元素

排序操作

is_sorted检测指定范围是否已排序
is_sorted_until返回最大已排序子范围
nth_element部分排序指定范围中的元素,使得范围按给定位置处的元素划分
partial_sort部分排序
partial_sort_copy拷贝部分排序的结果
sort(begin,end,cmp)对指定范围进行排序,默认升序排列,可定义比较函数cmp
stable_sort稳定排序

查找操作

binary_search(begin,end,val,cmp)判断范围中是否存在值等价于给定值的元素
equal_range(begin,end,val,cmp)返回给定范围中所有值等于给定值的元素组成的子范围的边界(等价于以下两个函数返回值组成的pair类型,该范围应先排序或由val划分)
lower_bound(begin,end,val,cmp)返回指向范围中第一个值大于或等于给定值的元素的迭代器
upper_bound(begin,end,val,cmp)返回指向范围中第一个值大于给定值的元素的迭代器

 

最大最小操作

is_permutation(begin1,end1,begin2)判断一个序列是否是另一个序列的一种排序
lexicographical_compare(begin1,end1,begin2,end2)比较两个序列的字典序,序列1字典序小于序列2则返回true
max(a,b)返回两个元素中值最大的元素
max_element(begin,end,cmp)返回给定范围中值最大的元素
min(a,b)返回两个元素中值最小的元素
min_element(begin,end,cmp)返回给定范围中值最小的元素
minmax(a,b)返回两个元素中值最大及最小的元素(pair)
minmax_element(begin,end,cmp)返回给定范围中值最大及最小的元素(pair)
next_permutation(begin,end,cmp)返回给定范围中的元素组成的下一个按字典序的排列
prev_permutation(begin,end,cmp)返回给定范围中的元素组成的上一个按字典序的排列

划分操作

is_partitioned(begin,end,pred)检测某个范围是否按指定谓词(Predicate)划分过
partition(begin,end,pred)将某个范围划分为两组,返回指向第二组首元素的迭代器
partition_copy(begin,end,result_true,result_false,pred)拷贝指定范围的划分结果到相应区域,返回拷贝后两组序列的尾迭代器
partition_point(begin,end,pred)返回指向被划分范围的划分点的迭代器
stable_partition(begin,end,pred)稳定划分,两组元素各维持相对顺序

集合操作

includes(begin1,end1,begin2,end2)判断第二个集合是否是另一个集合的子集,集合应先排序
inplace_merge(begin,middle,end)合并两个连续的有序序列,组成一个新的有序序列
merge(begin1,end1,begin2,end2,result)合并两个有序序列至一个新的有序序列result中,返回新序列的尾迭代器,下同。
set_difference(begin1,end1,begin2,end2,result)获得两个有序集合的差集A-B
set_intersection(begin1,end1,begin2,end2,result)获得两个集合的交集AB
set_symmetric_difference(begin1,end1,begin2,end2,result)获得两个集合的对称差
set_union(begin1,end1,begin2,end2,result)获得两个集合的并集

堆操作

C++中的堆,要基于向量使用。操作基于三个函数std::make_heapstd::push_heapstd::pop_heap,并且要配合push_backpop_back使用。

1.make_heap(begin,end,cmp) 根据给定范围及可选的比较函数建立堆。默认建立大顶堆,对int类型,可以在第三个参数传入greater<int>()  得到小顶堆。

2.push_heap(begin,end,cmp) 把指定区间的最后一个元素插入到堆中。只能基于已经是堆的容器添加数据,先将元素插入容器尾部再插入堆中。

3.pop_heap(begin,end,cmp) 弹出堆顶元素, 将其放置于区间末尾,重新建立堆。只能基于已经是堆的容器添加数据,将堆顶元素弹出至容器尾部后弹出容器。

4.sort_heap(begin,end,cmp) 堆排序算法,通过反复调用pop_heap弹出堆顶元素直到堆为空来得到有序序列,必须作用于堆。

5.is_heap(begin,end,cmp) 检测给定范围是否满足堆结构

6.is_heap_until(begin,end,cmp)检测给定范围中满足堆结构的最大子范围

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

void print(int x)
{
	cout << x << ' ';
}
int main()
{
	vector<int>v;
	for(int i=10;i>0;i--)
		v.push_back(i);

	cout << "创建小顶堆:" << endl;
	make_heap(v.begin(), v.end(),greater<int>());
	for_each(v.begin(), v.end(), print);
	cout <<endl;

	cout <<"向堆中添加元素4:"<<endl;
	v.push_back(4); 
    push_heap(v.begin(), v.end(),greater<int>());//新元素先推入向量在推入堆
	for_each(v.begin(), v.end(), print);
	cout <<endl;

	cout <<"弹出堆顶元素:" << endl;
	pop_heap(v.begin(), v.end(),greater<int>());
	for_each(v.begin(), v.end(), print);
	v.pop_back();//堆顶元素先推出堆,再推出向量

	cout <<endl<< "进行堆排序:" << endl;
	sort_heap(v.begin(), v.end(),greater<int>());
	for_each(v.begin(), v.end(), print);
	return 0;
}

 

其他

结构体定义

struct Point {
	int x, y;
	Point(int x=0,int y=0):x(x),y(y){}
};
Point a, b(3, 6);

结构体内定义构造函数Point,参数x,y默认为0,x(x),y(y)把成员变量x初始化为参数x,成员变量y初始化为参数y。定义变量Point a,b(3,6)分别调用了Point()(即Point(0,0))和Point(3,6)。也可以写成Point(int x=0,int y=0){this->x=x;this->y=y;},其中this为指向当前对象的指针。

 

操作符重载

Point operator+(const Point &a, const Point &b)
{
	return Point(a.x + b.x, a.y + b.y);
}
ostream& operator<<(ostream &out, const Point &a)
{
	out << "(" << a.x <<" "<< a.y << ")";
	return out;
}
cout << a + b << endl;

代码中重新定义了+和<<操作符,使结构体可以直接相加,输出。

 

 

模板

template <typename T>
T sum(T *begin, T *end)
{
	T *p = begin;
	T ans = 0;
	for (p; p != end; p++)
	{
		ans = ans + *p;
	}
	return ans;
}
Point a, b(3, 6), p[] = { Point(2,5),Point(3,2),Point(4,2) };
cout << sum(p, p + 3) << endl;

模板函数可以对任意已定义+操作符的类型求和。

template <typename T>
struct Point {
	T x, y;
	Point(T x = 0, T y = 0) :x(x), y(y) {}
};
template <typename T>
Point<T> operator + (const Point<T>& A, const Point<T>& B) 
{
	return Point<T>(A.x + B.x, A.y + B.y);
}
template <typename T>
ostream& operator << (ostream &out, const Point<T>& p) {
	out << "(" << p.x << "," << p.y << ")";
	return out;
}

为结构体Point定义模板,可以同时使用double,int型Point。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值