文章目录

  • 【STL编程】【竞赛常用】【part 1】
  • 【STL编程】【竞赛常用】【part 2】
    • 6. pair 容器
    • 7. set 集合容器
    • 8. multiset 多重集合容器
    • 9. map 映射容器
    • 10. multimap 多重映射容器
  • 【STL编程】【竞赛常用】【part 3】
    • 敬请期待!!!
    • 11. list 双向链表容器
    • 12. stack 堆栈容器
    • 13. queue 队列容器
    • 14. deque 双端队列容器
    • 15. priority_queue 优先队列容器

【STL编程】【竞赛常用】【part 1】

【STL编程】【竞赛常用】【part 1】

【STL编程】【竞赛常用】【part 2】

6. pair 容器

定义 解释
pair<T1, T2> p1; 创建一个空的pair对象,它的两个元素分别是T1和T2类型,采用值初始化
pair<T1, T2>p1(v1,v2): 创建一个pair对象,其中first成员初始化为v1,而second成员初始化为v2
make_pair(v1.v2) 以v1和v2值创建一个新的pair对象,其元素类型分别是v1和v2的类型
p1<p2 两个 pair 对象之间的小于运算,其定义遵循字典次序:如果p1.first<p2.first 或者!(p2.first<p1.first)&&(p1.second<p2. second),则返回true
p1==p2 如果两个pair 对象的firstsecond成员依次相等,则这两个对象相等
p.first 返回p中名为first的(公有)数据成员
p.second 返回p的名为second的(公有)数据成员
#include <bits/stdc++.h>
using namespace std;int main(){pair<int, double> p1; //使用默认构造函数p1.first = 10;p1.second = 12.5;cout << p1.first << ' ' << p1.second << endl;return 0;
}
/*
10 12.5
*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<string, double> psd; // typedef简化pair的声明为Recordint main(){psd p1 = make_pair("yjr", 100);psd p2;p2 = p1; //重载运算符"="cout << p2.first << ' ' << p2.second << endl;return 0;
}
/*
yjr 100
*/

pair 的比较是按照字典序比较的,比较时先按照first 的大小比较,如果相等,再按second 的大小比较:

// pair 的比较
#include <bits/stdc++.h>
using namespace std;int main(){pair<int, char> A(10, 'z');pair<int, char> B(90, 'a');if (A == B)cout << "相等\n";if (A != B)cout << "不相等\n";if (A < B)cout << "A<B\n";if (A > B)cout << "A>B\n";if (A <= B)cout << "A<=B\n";if (A >= B)cout << "A>=B\n";return 0;
}
/*
不相等
A<B
A<=B
*/

7. set 集合容器

set集合容器在头文件<set>中声明,使用类似于树的结构(基于红黑树的平衡二叉检索树),存储数据并自动将数据(无重复值)由小到大排列。构造set集合容器的主要目的是快速检索(时间复杂度为O(logN)),检索效率高于vector、deque及list等容器。

访问set集合容器中的元素,需要通过迭代器进行。迭代器类似于指针,可以通过它指向容器中的某个元素的地址。例如set<int>::iterator ii;定义了一个set<int>类型的迭代器为ii

方法 解释
s.begin() 返回set容器的第一个元素
s.end() 返回set容器的最后一个元素
s.clear() 删除set容器中的所有的元素
s.empty() 判断set容器是否为空
s.insert() 插入一个元素
s.erase() 删除一个元素
s.size() 返回当前set容器中的元素个数
s.lower_bound() 返回第一个大于或等于给定关键值的元素
s.upper_bound() 返回第一个大于给定关键值的元素
s.equal_range() 返回一对定位器,分别表示 第一个大于或等于给定关键值的元素 和 第一个大于给定关键值的元素,这个返回值是一个pair类型,如果这一对定位器中哪个返回失败,就会等于 s.end()
#include <bits/stdc++.h>
using namespace std;int main(){set<int> s;for (int i = 10; i > 0; --i) //此处由大到小赋值s.insert(i);             //插入元素set<int> s2(s);              //拷贝s生成s2s.erase(s.begin());          //删除操作s.erase(6);s.insert(5);                              //不会重复插入set<int>::iterator ii;                    // ii为前向迭代器for (ii = s.begin(); ii != s.end(); ii++) //遍历cout << *ii << ' ';cout << "\n元素个数为" << s.size(); //统计set中元素个数,时间复杂度O(1)ii = s.find(10);                    //查找元素值,并返回指向该元素的迭代器if (ii != s.end())                  //如容器中不存在该元素,返回值等于s.end()cout << "\n查找=" << *ii;if (s.count(5)) //返回set中值为5的元素个数,时间复杂度为O(log n)cout << "\n存在元素5";s.clear(); //清空所有元素cout << "\n元素是否为空:" << s.empty();return 0;
}/*2 3 4 5 7 8 9 10元素个数为8查找=10存在元素5元素是否为空:1
*/
#include<bits/stdc++.h>
using namespace std;int main(){set<int> myset;for (int i = 1; i < 11; i++){myset.insert(i);}cout << "lower_bound & upper_bound test:" << endl;cout << "第一个大于等于3的元素:" << *myset.lower_bound(3) << endl; //函数实际返回地址值cout << "第一个大于3的元素:" << *myset.upper_bound(3) << endl;  cout << "equal_range test:" << endl;cout << "第一个大于或等于2的元素: " << *myset.equal_range(2).first << endl;cout << "第一个大于2的元素: " << *myset.equal_range(2).second << endl;if (myset.equal_range(20).first == myset.end())cout << "不存在大于等于20的元素" << endl;myset.clear();return 0;
}
/* 第一个大于等于3的元素:3第一个大于3的元素:4equal_range test:第一个大于或等于2的元素: 2第一个大于2的元素: 3不存在大于等于20的元素*/

使用insert()将元素插入set集合容器的时候,集合容器默认按由小到大的顺序插入元素,然而在很多情况下(例如需要由大到小排序)需要自行编写比较函数。

// set的比较函数
#include <bits/stdc++.h>
using namespace std;struct Comp{bool operator()(const int &a, const int &b){return a > b; //从大到小排序// return a < b;  //从小到大排序}
}; //需在结构体内定义比较函数int main(){set<int, Comp> s;             // set调用的比较函数为Compfor (int i = 1; i <= 10; ++i) //此处是由小到到赋值s.insert(i);set<int>::iterator ii;for (ii = s.begin(); ii != s.end(); ii++) //遍历cout << *ii << ' ';return 0;
}
/*10 9 8 7 6 5 4 3 2 1
*/

重载操作符可以使得自定义类型像基本数据类型一样支持加、减、乘、除、自加、自减等各种操作。operator是C++的关键字,它和操作符(例如“ () ”)一起使用,表示运算符重载函数,在理解时可将operator和运算符(例如“operator()”)视为函数名。

参数定义为const int &aconst int &b这种形式,一是防止a和b被修改,二是通过引用变量的方式减少系统开销。末尾的const也是为了防止被修改。

实际上,很多C++操作符已经被重载了,例如 “*” 用于两个数字之间时,得到的是它们的乘积;用于一个地址之前时,得到的是这个地址上存储的值。cin>>x和cout<<x中的“>>”和“<<”运算符也被重载了。

例如自定义一个结构体Time类型,并想实现两个Time类型相加的操作(即小时与小时相加,分钟与分钟相加,秒与秒相加),其程序可能如下所示。

#include <bits/stdc++.h>
using namespace std;struct Time{int H, M, S;                        //时,分,秒Time operator+(const Time &b) const //重载运算符"+"{return Time{H + b.H, M + b.M, S + b.S}; //仅为演示,不考虑进位}
} T1 = {3, 2, 4}, T2 = {5, 20, 30}, T3;int main(){T3 = T1 + T2;cout << T3.H << ":" << T3.M << ":" << T3.S << endl;return 0;
}
/*8:22:34
*/

C++只能重载已有的操作符。下表列出了可以被重载的操作符。


当元素是结构体时,必须要重载运算符“<”:

// set的结构体排序
#include <bits/stdc++.h>
using namespace std;struct Info{string name;double score;bool operator<(const Info &a) const  {//重载"<"操作符,照抄即可return a.score < score; //从大到小排序// return a.score >score;  //从小到大排序}
} info;int main(){set<Info> s;info = {"A", 90.0};s.insert(info);info = {"B", 92.0};s.insert(info);info = {"C", 96.0};s.insert(info);set<Info>::iterator ii;for (ii = s.begin(); ii != s.end(); ii++) //遍历cout << (*ii).name << ' ' << (*ii).score << endl;return 0;
}
/*C 96B 92A 90
*/

8. multiset 多重集合容器

multiset多重集合容器在头文件<set>中定义,它可以看成序列,序列中可以存在重复的数。multiset能时刻保证序列中的数是有序的(默认从小到大排序),插入一个数或删除一个数都能够在O(logn)的时间内完成。

#include <bits/stdc++.h>
using namespace std;int main(){multiset<int> m;m.insert(11); //插入数据m.insert(21);m.insert(10);m.insert(12);m.insert(12);m.insert(11);m.insert(11);m.insert(11);m.insert(9);cout << "11的个数有" << m.count(11) << endl; //输出multiset中11的个数cout << "第一个大于等于10的元素为:" << *m.lower_bound(10) << endl;cout << "第一个大于11的元素为:" << *m.upper_bound(11) << endl;multiset<int>::iterator it;for (it = m.begin(); it != m.end(); it++)cout << *it << endl;                            //从小到大输出cout << "删除12,有" << m.erase(12) << "个" << endl; //删除等于12的元素cout << "查找9\n";multiset<int>::iterator i = m.find(9); //查找v,返回该元素的迭代器位置if (i != m.end())                      //找到则输出,否则i为end()迭代器位置cout << *i << endl;pair<multiset<int>::iterator, multiset<int>::iterator> p;int v = 11;// equal_range:有序容器中表示一个值第一次出现与最后一次出现的后一位p = m.equal_range(v); //查找所有相同元素cout << "大于等于" << v << "的第一个元素为" << *p.first << endl;cout << "大于" << v << "的第一个元素为" << *p.second << endl;cout << "键值为" << v << "的全部元素为";for (it = p.first; it != p.second; it++) //打印重复键值元素11cout << *it << " ";m.clear(); //清空所有元素return 0;
}
11的个数有4
第一个大于等于10的元素为:10
第一个大于11的元素为:12
9
10
11
11
11
11
12
12
21
删除12,有2个
查找9
9
大于等于11的第一个元素为11
大于11的第一个元素为21
键值为11的全部元素为11 11 11 11

9. map 映射容器

map映照容器在头文件<map>中定义,它的元素数据是由键值和映照数据组成的,键值与映照数据之间具有一一对应的关系。

map映照容器和set集合容器一样都是采用红黑树来实现的,插入键值的元素不允许重复,元素默认是按键值由小到大排序的。如果定义比较函数,比较函数也只能对元素的键值进行比较,元素的各项数据可通过键值检索出来。
mapset的区别是:map是处理带有键值的记录型元素数据的快速插入、删除及检索,而set是对单一数据的处理。

方法 解释
begin() 返回指向map头部的迭代器
end() 返回指向map末尾的迭代器
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数(因为key值不会重复,所以只能是1 or 0)
empty() 如果map为空则返回true
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
insert() 插入元素
size() 返回map中元素的个数
swap() 交换两个map
get_allocator() 返回map的配置器
key_comp() 返回比较元素key的函数
value_comp() 返回比较元素value的函数
lower_bound() 返回键值>=给定元素的第一个位置
upper_bound() 返回键值>给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
size() 返回map中元素的个数
swap() 交换两个map
#include <bits/stdc++.h>
using namespace std;int main(){map<int, string> ms;ms[1] = "student_one";ms[1] = "student_two"; // id相同,则覆盖ms[2] = "student_three";map<int, string>::iterator iter;ms.insert(make_pair(3, "student_four")); //插入新元素for (iter = ms.begin(); iter != ms.end(); iter++)cout << iter->first << " " << iter->second << endl;cout << endl;iter = ms.lower_bound(1); //首个大于等于1的元素cout << iter->second << endl;iter = ms.upper_bound(1); //首个大于1的元素cout << iter->second << endl;iter = ms.find(1); //查找键值为1的元素位置ms.erase(iter);    //删除键值为1的元素for (iter = ms.begin(); iter != ms.end(); iter++)cout << iter->first << " " << iter->second << endl;ms.erase(ms.begin(), ms.end()); //删除全部元素cout <<"size: "<< ms.size() << endl;cout <<"empty: "<< ms.empty() << endl;// empty()判断map是否为空return 0;
}

结果:

1 student_two
2 student_three
3 student_fourstudent_two
student_three
2 student_three
3 student_four
size: 0
empty: 1
#include <bits/stdc++.h>
using namespace std;struct Info{ //学生信息结构体char *xm; //姓名int y;    //年份char *d;  //地址
};struct Record {//学生记录结构体int id;  //学号作键值Info sf; //学生信息作映照数据
};int main(){Record srArray[] ={{4, "Li", 21, "beijing"},{2, "wang", 29, "shanghai"},{3, "zhang", 30, "shengzheng"}};map<int, Info, greater<int>> m; //按键值由大到小排序for (int j = 0; j < 3; j++)     //装入三个学生信息m[srArray[j].id] = srArray[j].sf;Record s1 = {5, "Ling", 23, "XINJIANG"};m.insert(make_pair(s1.id, s1.sf)); //插入新生信息map<int, Info>::iterator i;for (i = m.begin(); i != m.end(); i++) //正向遍历cout << (*i).first << ' ' << (*i).second.xm << ' ' << (*i).second.d << '\n';i = m.find(2); //查找键值为2的记录并输出cout << "Key value 2: " << (*i).second.xm << ' ' << (*i).second.d;return 0;
}

结果:

5 Ling XINJIANG
4 Li beijing
3 zhang shengzheng
2 wang shanghai
Key value 2:wang shanghai

10. multimap 多重映射容器

multimapmap 的功能基本相同,唯独不同的是multimap 允许插入重复键值的元素,由于允许插入重复键值的元素,因此multimap 的元素插入、删除以及查找与map不同。

#include <bits/stdc++.h> //使用万能头文件,无需写#include <map>
using namespace std;int main(){multimap<string, double> mp;                    //定义map对象,当前没有任何元素mp.insert(pair<string, double>("Jack", 300.5)); //插入元素amp.insert(pair<string, double>("Kity", 200));mp.insert(pair<string, double>("Memi", 500));mp.insert(pair<string, double>("Jack", 306)); //重复插入键值"Jack"multimap<string, double>::iterator it;mp.erase("Jack");                           //删除键值等于"Jack"的元素for (it = mp.begin(); it != mp.end(); it++) //前向迭代器中序遍历multimapcout << (*it).first << " " << (*it).second << endl;it = mp.find("Nacy"); //元素的查找if (it != mp.end())   //找到cout << (*it).first << " " << (*it).second << endl;else //没找到cout << "Not find it!" << endl;return 0;
}

结果:

Kity 200
Memi 500
Not find it!

【STL编程】【竞赛常用】【part 3】

敬请期待!!!

11. list 双向链表容器

12. stack 堆栈容器

13. queue 队列容器

14. deque 双端队列容器

15. priority_queue 优先队列容器

【STL编程】【竞赛常用】【part 2】相关推荐

  1. 如何通过编程竞赛来掌握C++编程

    如何通过编程竞赛来掌握C++编程 一.为什么选择编程竞赛作为学习C++的方法 1 提升编程能力的有效途径 2 压力激发潜力,激发学习动力 3 增加编程实践机会,锻炼实战技能 4 社区交流,收获学习经验 ...

  2. Trie(字典树)解析及其在编程竞赛中的典型应用举例

    摘要: 本文主要讲解了Trie的基本思想和原理,实现了几种常见的Trie构造方法,着重讲解Trie在编程竞赛中的一些典型应用. 什么是Trie? 如何构建一个Trie? Trie在编程竞赛中的典型应用 ...

  3. Github项目推荐 | OI Wiki:编程竞赛最全知识整合站点

    编程竞赛发展多年,难度越来越高,内容越来越复杂,而网上资料大多零散,初学者往往并不知道如何系统地学习相关知识,需要花费大量时间摸索. OI (Olympiad in Informatics,信息学奥林 ...

  4. 游戏编程之常用设计模式

    游戏编程之常用设计模式 作者:老九-技术大黍 社交:知乎 公众号:老九学堂(新人有惊喜) 特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系笔者授权 前言 一说到设计模式,可能大家会想到Jav ...

  5. 【CSDN编程竞赛】赛后总结

    CSDN编程竞赛报名地址:https://edu.csdn.net/contest/detail/16 (请不要删掉此地址) 努力是为了让自己不平庸,你参加过哪些竞赛,有哪些收获?快来分享一下你的参赛 ...

  6. 基于TI器件的电子竞赛常用模拟系统设计与实践

    基于TI器件的电子竞赛常用模拟系统设计与实践 第一讲 理想运放模型 理想运放模型![[Pasted image 20220710094850.png]] 叠加定理计算运算输出![[FZ0%[4~XO] ...

  7. C++ STL编程轻松入门基础

    C++ STL编程轻松入门基础 1 初识STL:解答一些疑问 1.1 一个最关心的问题:什么是STL 1.2 追根溯源:STL的历史 1.3 千丝万缕的联系 1.4 STL的不同实现版本 2 牛刀小试 ...

  8. 【青少年编程竞赛交流】03月份微信图文索引

    03月份微信图文索引 由于"组队学习"这个公众号的功能主要是组织Datawhale社群中的学习者们每个月的组队学习,所以,我另外新建了这个微信公众号"青少年编程竞赛交流& ...

  9. 青少年编程竞赛交流群第050次活动录播

    背景介绍 把电子学会的青少年编程能力等级测评作为游戏的关卡,带着小朋友们升级打怪,这个想法来自于 我从邵慧宁身上得到的启发. 升级打怪: 电子学会考评中心:http://www.qceit.org.c ...

最新文章

  1. Java实现网页截屏功能(基于phantomJs)
  2. Statement接口实现查询数据、添加数据
  3. 支付方式之线上和线下
  4. 计算机操作系统:存储器的管理
  5. yolo_model to output理解
  6. bzoj3224: Tyvj 1728 普通平衡树(splay)
  7. MVC4建立DBContext的EF6数据
  8. 领诵员冯琳最新消息!保研复旦、主持卫视跨年晚会
  9. 容器中apscheduler不执行_APScheduler:定时任务框架
  10. c语言遍历文件内容_C/C++编程笔记:C语言开发电脑益智游戏【扫雷】(源代码分享)...
  11. 安装第三方插件BeautifulSoup
  12. js获取时间(本周、本季度、本月..)
  13. inotify实时同步工具理论和实战
  14. Mongoose 参考手册
  15. Hadoop开发环境
  16. 浅谈SpringMVC源码的SpringServletContainerInitializer的完整加载流程
  17. java移位运算详解
  18. mysql 数据库数据恢复 库被删了怎么恢复数据库
  19. SpringBoot中配置文件dev、test、和prod各自代表什么意思?
  20. 计算机网络密码忘记了怎么办,忘记电脑密码怎么办?--重置电脑密码的方法详解...

热门文章

  1. Pointnet++中tf_ops三个.so文件的生成
  2. MNE学习笔记(六):Epoched data的可视化
  3. Vue开发警告[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
  4. outlook服务器响应错误,outlook 错误代码解析与解决方法
  5. Adobe PS常用快捷键
  6. Android 9.0系统源码_SystemUI(四)通知图标控制器
  7. js bind 传参、_Node.js 在微医的应用场景及实践
  8. 浅谈一个新人的大数据之路-HiveQLSpark-SQL中谓词下推
  9. TCP连接大量CLOSE_WAIT状态问题排查
  10. Git:git pull 冲突 清除 staged