C++算法竞赛中常用的STL

本文详细介绍了C++标准模板库(STL)中的多种容器及其使用方法,包括动态数组vector、栈stack、队列queue、集合set、映射map、优先队列priority_queue,并提供了丰富的示例代码。

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

快考CSP了,C/C++玩家的福利来了

首先介绍下,什么是STL。STL,Standard Template Library的缩写,标准模版库的意思。STL是一些“容器”的集合,这些容器包括list、 vector、set、queue等。

PS:这里说明下,文中出现的DataType指数据类型,DataName指变量名,cmp指一个返回类型为bool的比较函数

iterator 迭代器:

要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。

迭代器按照定义方式分成以下四种。

  1. 正向迭代器,定义方法如下:
    容器类名::iterator 迭代器名;

  2. 常量正向迭代器,定义方法如下:
    容器类名::const_iterator 迭代器名;

  3. 反向迭代器,定义方法如下:
    容器类名::reverse_iterator 迭代器名;

  4. 常量反向迭代器,定义方法如下:
    容器类名::const_reverse_iterator 迭代器名;

迭代器用法示例会在后边不同容器示例中展示。

vector 动态数组

所谓动态数组,就是不定长数组。

头文件:#include<vector>

声明:vector<DataType> DataName;

基本操作:

  • push_back();,在最后面插入一个新元素
  • size(),返回vector的长度
  • clear(),清空vector
  • 可以像数组一样使用。

例子:

vector<int> vec;	//空的
vec.push_back(0);	//有0
vec.push_back(1);	//有0,1
vec.push_back(2);	//有0,1,2
//两种遍历方法
for(int i=0; i<vec.size(); i++){
	printf("%d\n",vec[i]);
}
for(vector<int>::iterator it=vec.begin(); it!=vec.end(); it++){
	printf("%d\n",*it);//迭代器访问
}

vec[1]=3;	//变成0,3,3
vec[2]=2;	//变成0,3,2

vec.clear();//清空

stack 栈

先进后出的数据结构(FILO)

头文件:#include<stack>

声明:stack<DataType> DataName;

基本操作:

  • push(),入栈
  • pop(),出栈
  • top(),访问栈顶元素
  • empty(),判断栈空
  • size(),返回栈中元素个数

例子:

s.push(1);	//{1}
s.push(233);	//{233,1}
s.push(666);	//{666,233,1}
cout<<s.top()<<endl;	//输出栈顶666
cout<<s.size()<<endl;	//输出栈中元素个数3
s.pop();	//{233,1}
s.push(2);	//{2,233,1} 

queue 单向队列

先进先出的数据结构(FIFO)

头文件:#include<queue>

声明:queue<DataType> DataName;

基本操作:

  • push(),入队
  • pop(),出队
  • front(),访问队首元素
  • back(),访问队尾元素
  • empty(),判断队空
  • size(),返回队列元素个数

例子:

int e,m,n;
queue<int> q1;
for(int i=0;i<10;i++)
	q.push(i);	//入队 
//[0,1,2,3,4,5,6,7,8,9]
if(!q1.empty())
	cout<<"no empty\n";
n=q1.size();	//n=10
m=q1.back();	//m=9
for(int i=0;i<n;i++){
	e=q1.front();	//取队首元素
	cout<<e<<" ";
	q1.pop();	//出队 
}
cout<<endl;
if(q1.empty())
	cout<<"queue is empty"; 

set 集合

集合中不会存在重复元素,支持高效的插入、删除和查询操作,复杂度均是O(logn)(对比使用数组来实现,虽然插入的时间复杂度O(1),但是删除和查询的时间复杂度却是O(n))。

头文件:#include<set>

声明:set<DataType> DataName;

基本操作:

  • begin(),返回set第一个元素(类型为迭代器,或者说指针)
  • end(),返回set最后一个元素(同上)
  • clear(),清空set中的元素
  • empty(),判断set是否为空
  • insert(),插入一个元素
  • erase(),删除一个元素
  • find(),查找一个元素,返回为迭代器
  • size(),返回set的元素个数

例子:

set<int> s;
set<int>::iterator it;

s.insert(1);	//{1}
s.insert(2);	//{1,2}
s.insert(3);	//{1,2,3}
s.insert(1);	//{1,2,3}
s.erase(1);		//{2,3}

it=s.find(2);	//查找元素2,若未找到,返回s.end() 

map 映射

从一个元素映射到另一个元素的数据结构,hash是他的一种。

头文件:#include<map>

声明:map<DataTypeA,DataTypeB> DataName;从DataTypeA映射到DataTypeB

基本操作:

  • 可以像数组一样使用
  • 迭代器有两个属性,first代表key,second代表value
  • count(),判断是否存在映射
  • clear(),清空map

例子:

map<string,int> dict;	//{}
dict["Tom"]=1;	//{"Tom":1}
dict["Jone"]=2;	//{"Tom":1,"Jone":2}
dict.insert(map<string,int>::value_type("Mary",1));
// //{"Tom":1,"Jone":2,"Mary":1}
if(dict.count("Mary")){
	printf("Mary存在");
} else{
	printf("Mary不存在");
}
//迭代器访问 
for(map<string,int>::iterator it=dict.begin(); it!=dict.end(); it++){
	cout<<it->first<<":"<<it->second<<endl;
}

priority_queue 优先队列

实质就是二叉堆,使用该模版可以快速实现小根堆、大根堆。插入、删除、查询的时间复杂度均是O(logn)。

头文件:#include<priority_queue>

声明: 默认小根堆,priority_queue<DataType> DataName;

自定义比较函数,priority_queue<DataType,vector<DataType>,cmp> DataName;

基本操作:

  • push(),队尾插入元素
  • pop(),取出队首元素
  • top(),访问队首元素
  • size(),获取队列长度
  • clear(),清空队列

例子:

struct cmp{
	bool operator() (const int &a,const int &b){//&引用 
		return a>b;	//最大堆 
	} 
};

priority_queue<int,vector<int>,cmp> q;//[]
q.push(2); //[2]
q.push(1); //[2,1]
q.push(3); //[3,2,1]

for(int i=0;i<q.size();i++){
	printf("%d\n",q.top());//逐个输出队首
	q.pop();//出队 
}

sort 快排函数

头文件:#include<algorithm>

sort(begin,end,cmp);//begin为序列开始地址,end序列结束地址,cmp比较函数,cmp可以不填,默认升序

数组排序:

int a[4]={2,4,3,1};
int n=4;
sort(a,a+n);

vector排序:

sort(vec.begin(),vec.end());

结构体排序:

struct Point{
	int x,y;
}p[4]={{1,2},{1,0},{2,1},{0,1}}; 

bool cmp(Point a,Point b){
	//比较函数,x为主关键字升序,y为次关键字升序 
	if(a.x==b.x) return a.y<b.y;
	return a.x<b.x;
}

int main(){
	sort(p,p+4,cmp);
	return 0;
}
<think>我们正在讨论C++STL在编程竞赛中的常用功能。根据用户需求,我们需要总结竞赛常用STL组件及其用法。参考引用中提到了vector、string、algorithm中的sort和reverse等,这些都是竞赛中的核心工具。根据引用[4]中的内容,C++STL包含多个容器和算法,如vector、stack、queue、deque、priority_queue、map、set、pair、string、bitset、array、tuple等。同时,algorithm头文件中的sort、reverse等函数也非常重要。在竞赛编程中,常用功能包括:1.容器:vector(动态数组)、string(字符串处理)、stack(栈)、queue(队列)、priority_queue(优先队列,即堆)、map(映射,基于红黑树)、set(集合)、unordered_map和unordered_set(哈希表)等。2.算法:sort(排序)、reverse(反转)、lower_bound/upper_bound(二分查找)、next_permutation(全排列)等。3.其他:pair(二元组)、tuple(元组)、bitset(位集)等。我们将重点介绍竞赛中最常用的几个部分,并给出示例代码。注意:在竞赛编程中,通常使用简洁的写法,例如使用usingnamespacestd;,但注意在实际大型项目中避免使用。下面按照常用程度和重要性进行介绍。</think>### C++ STL 常用功能总结(竞赛编程) 以下是竞赛编程中最常用C++ STL 组件及其核心用法,结合引用内容整理: --- #### 1. **`vector` 动态数组** [^2][^4] ```cpp #include <vector> using namespace std; vector<int> v; // 声明 v.push_back(10); // 末尾添加元素 v.pop_back(); // 删除末尾元素 v.size(); // 获取大小 v.resize(5); // 调整大小 vector<int> v2(10, 0); // 10个元素初始化为0 v[3] = 7; // 随机访问 ``` --- #### 2. **`algorithm` 算法库** [^1][^3][^4] ```cpp #include <algorithm> using namespace std; // 排序(默认升序) sort(v.begin(), v.end()); sort(v.begin(), v.end(), greater<int>()); // 降序 // 反转 reverse(v.begin(), v.end()); // 二分查找(需先排序) auto pos = lower_bound(v.begin(), v.end(), 5); // 首个≥5的位置 // 全排列 next_permutation(v.begin(), v.end()); ``` --- #### 3. **`string` 字符串处理** [^4] ```cpp #include <string> using namespace std; string s = "abc"; s += "def"; // 拼接 s.substr(1, 3); // 子串("bcd") s.find("cd"); // 查找位置 sort(s.begin(), s.end()); // 字典序排序 to_string(123); // 数字转字符串 stoi("456"); // 字符串转数字 ``` --- #### 4. **`queue` & `stack` 容器适配器** [^4] ```cpp #include <queue> #include <stack> queue<int> q; // FIFO q.push(1); // 入队 q.pop(); // 出队 stack<int> st; // LIFO st.push(2); // 入栈 st.pop(); // 出栈 ``` --- #### 5. **`map`/`set` 关联容器** [^4] ```cpp #include <map> #include <set> map<string, int> m; // 键值对 m["apple"] = 5; // 插入/更新 auto it = m.find("pear");// 查找 set<int> s; // 有序集合 s.insert(10); // 插入 s.erase(5); // 删除 ``` --- #### 6. **`priority_queue` 优先队列** [^4] ```cpp #include <queue> priority_queue<int> pq; // 大顶堆 priority_queue<int, vector<int>, greater<int>> minHeap; // 小顶堆 pq.push(3); // 插入元素 pq.top(); // 获取堆顶 pq.pop(); // 删除堆顶 ``` --- #### 7. **实用工具** [^4] ```cpp #include <utility> // pair #include <tuple> // tuple pair<int, string> p = {1, "a"}; auto [x, y] = p; // C++17结构化绑定 tuple<int,double,char> t(1, 2.0, 'c'); auto val = get<1>(t); // 获取第2个元素 ``` --- ### 竞赛技巧总结 1. **性能优先**:`unordered_map/unordered_set`(哈希表)比`map/set`更快,但无序 2. **减少拷贝**:使用引用传参 `void func(vector<int>& v)` 3. **预分配内存**:`vector.reserve(1000)` 避免动态扩容开销 4. **Lambda表达式**:自定义排序规则 ```cpp sort(v.begin(), v.end(), [](int a, int b){ return abs(a) < abs(b); // 按绝对值排序 }); ``` > 完整 STL 参考见 [C++ STL 详解](https://example.com/stl-guide)[^4] --- ###
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寒商

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值