1. STL基本概念
1.1 STL六大组件
STL六大组件:容器、算法、迭代器、仿函数、适配器、空间适配器
2.4 STL中容器、算法、迭代器
2.5 容器算法 迭代器
2.5.1 vector存放内置数据类型
容器:vector
算法:for_each
迭代器:vector::iteartor
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
void myPrint(int val){
cout<<val<<endl;
}
void test01(){
vector<int> v;
v.push_back(2);
v.push_back(3);
v.push_back(4);
//通过迭代器访问
vector<int>::iterator itB = v.begin();
vector<int>::iterator itE = v.end();
//第一种遍历方式
while(itB != itE){
cout<<*itB<<endl;
itB++;
}
//第二种遍历
for(vector<int>::iterator it = v.begin();it!=v.end();it++){
cout<<*it<<endl;
}
//第三种遍历
for_each(v.begin(),v.end(),myPrint);
}
int main() {
test01();
return 0;
}
2.5.2 vector存放自定义数据
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
class Person{
public:
Person(string n,int a){
name = n;
age = a;
}
string name;
int age;
};
void test01(){
vector<Person*> v;
Person p1("aa",12);
Person p2("bb",24);
Person p3("cc",13);
v.push_back(&p1);
v.push_back(&p2);
v.push_back(&p3);
for(vector<Person*>::iterator it=v.begin();it!=v.end();it++){
cout<<(*it)->name<<" "<<(*it)->age<<endl;
}
}
int main() {
test01();
return 0;
}
2.5.3 vector容器嵌套容器
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
void test01(){
vector<vector<int>> v;
vector<int> v1 = {1,24,5};
vector<int> v2 = {5,4,1};
vector<int> v3 = {10,5,3,2};
v.push_back(v1);
v.push_back(v2);
v.push_back(v3);
for(vector<vector<int>>::iterator it = v.begin();it!=v.end();it++){
// (*it) -- == vector<int>'
for(vector<int>::iterator vit = (*it).begin();vit!=(*it).end();vit++){
cout<<*vit<<" ";
}
cout<<endl;
}
}
int main() {
test01();
return 0;
}
3.1.1 string基本概念
3.1.2 string 构造函数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//string 构造函数
void test01(){
string s1; //默认构造
const char* str = "hefg";
string s2(str); //字符串str初始化
cout<<s2<<endl;
string s3(s2); //拷贝构造
cout<<s3<<endl;
string s4(12,'f'); //使用n个 char字符初始化
cout<<s4<<endl;
}
int main() {
test01();
return 0;
}
3.1.3 string赋值操作
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//string 构造函数
void test01(){
string str1;
str1 = "hello"; //第一种
string str2;
str2 = str1; //第二种
string str3;
str3 = 'a'; //3
string str4;
str4.assign("hell"); //4
string str5;
str5.assign("hello c++",4); //5
string str6;
str6.assign(str5); //6
string str7;
str7.assign(12,'r'); //7
}
int main() {
test01();
return 0;
}
3.1.4 string 字符串拼接(字符串末尾拼接字符)
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//string 拼接
void test01(){
string str1 = "";
str1 += "hello"; //第一种
str1 += ':'; //2
string str2 = "lol dnf";
str1 += str2; //3
string str3 = "I";
str3.append(" love"); //4
// I love game
str3.append("game ab",4); //5 前4个拼接到str3
//I love game lol dnf
str3.append(str2);
//I love game lol dnf lol
str3.append(str2,0,3); //6 从str2的第0个位置,截取3个字符
}
int main() {
test01();
return 0;
}
3.1.5 string查找和替换
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//string 查找和替换
//1.查找
void test01(){
string str1 = "abcde";
cout<<str1.find("de")<<endl; //第一种(查找子串) 输出3
//rfind和find区别:
//rfind 从右往左 find从左往右
cout<<str1.rfind("de")<<endl; //2 输出3
}
//2.替换
void test02(){
string str1 = "abcdegf";
str1.replace(1,3,"1111"); //从下标1开始,3个字符替换为1111
cout<<str1<<endl; //输出 a1111egf
}
int main() {
test02();
return 0;
}
3.1.6 string字符串比较
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//字符串比较
void test01(){
string str1 = "hello";
string str2 = "hello";
if(str1.compare(str2) == 0){
cout<<"=="<<endl;
}
str1 = "xello";
str2 = "hello";
if(str1.compare(str2) > 0){
cout<<"str1 > str2"<<endl;
}
}
int main() {
test02();
return 0;
}
3.1.7 string字符存取
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//字符串比较
void test01(){
string str1 = "hello";
//通过[]
for(int i=0;i<str1.size();i++){
cout<<str1[i]<<" ";
}
cout<<endl;
//通过at
for(int i=0;i<str1.size();i++){
cout<<str1.at(i)<<" ";
}
cout<<endl;
//修改单个字符
str1[0] = 'w';
cout<<"str ="<<str<<endl;
str1.at(0) = 'g';
}
int main() {
test01();
return 0;
}
3.1.8 string插入和删除
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//字符串插入和删除
void test01(){
string str1 = "hello";
//插入
str1.insert(1,"111"); //从第1个位置,插入111
//输出 h111ello
cout<<str1<<endl;
//删除 从第1个位置,删除3个
str.erase(1,3); //变为 hello
}
int main() {
test01();
return 0;
}
3.1.9 子串
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//string 子串
void test01(){
string str1 = "abcdef";
// 从第1个位置 截取3个
string stS = str1.substr(1,3);
cout<<stS<<endl; //输出 bcd
}
//实用操作
void test02(){
string email = "zhangsan@eamil.com";
//从邮件地址中 获取用户信息
int pos = email.find("@");
string userName = email.substr(0,8);
//输出zhangsan
cout<<userName<<endl;
}
int main() {
test01();test02();
return 0;
}
3.2 vector容器
3.2.1 vector基本概念
3.2.2 vector构造函数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector 容器构造
void printVector(vector<int>&v){
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<endl;
}
}
void test01(){
vector<int> v; //默认构造
for(int i=0;i<10;i++){
v.push_back(i);
}
printVector(v);
//通过区间方式构造
vector<int>v2(v1.begin(),v1.end());
// n个elem构造
vector<int>v3(10,100); //10个100
//拷贝构造
vector<int>v4(v3);
}
int main() {
test01();
return 0;
}
3.2.3 vector赋值操作
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector 赋值
void printVector(vector<int>&v){
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
}
void test01(){
vector<int> v; //默认构造
for(int i=0;i<10;i++){
v.push_back(i);
}
printVector(v);
//直接赋值
vector<int>v2 = v;
printVector(v2);
//assign
vector<int> v3;
v3.assign(v.begin(),v.end());
printVector(v3);
//n个elem方式
vector<int> v4;
v4.assign(10,100); //10个100
}
int main() {
test01();
return 0;
}
vector容器容量和大小
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector 容量和大小
void printVector(vector<int>&v){
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
}
void test01(){
vector<int> v; //默认构造
for(int i=0;i<10;i++){
v.push_back(i);
}
if(v.empty()){ //为真 代表容器为空
//为空
}else{
cout<<"v容量为:"<<v.capacity()<<endl; //16
cout<<"v大小为:"<<v.size()<<endl; //10
}
//重新指定大小,若重新指定的比原来长了,则默认补0
v.resize(15,100); //利用重载,将默认补0换为100
printVector(v);
v.resize(5); //若重新指定比原来短,则会删除多余的
}
int main() {
test01();
return 0;
}
3.2.5 vector插入和删除
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector 插入和删除
void printVector(vector<int>&v){
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
vector<int> v; //默认构造
for(int i=0;i<10;i++){
v.push_back(i);
}
//尾删除
v.pop_back();
printVector(v);
//插入 //在第一个位置插入100,insert第一个参数是 迭代器
v.insert(v.begin(),100);
v.insert(v.begin(),2,1000); //第一个位置插入2个1000
//删除 删除第一个位置数据,参数也是迭代器
v.erase(v.begin());
printVector(v);
// 全部删除了 类似清空 v.clear();
v.erase(v.begin(),v.end());
}
int main() {
test01();
return 0;
}
3.2.6 vector数据存取
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector 数据存取
void printVector(vector<int>&v){
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
vector<int> v; //默认构造
for(int i=0;i<10;i++){
v.push_back(i);
}
//中括号方式访问
for(int i=0;i<v.size();i++){
cout<<v[i]<<" ";
}
cout<<endl;
//利用at
for(int i=0;i<v.size();i++){
cout<<v.at(i)<<" ";
}
cout<<endl;
//获取第一个元素
cout<<v.front()<<endl;
//获取最后一个元素
cout<<v.back()<<endl;
}
int main() {
test01();
return 0;
}
3.2.7 vector互换容器
功能描述:实现两个容器内元素进行互换
函数原型: swap(vec); //将vec与本身的元素互换
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector容器互换
void printVector(vector<int>&v){
for(vector<int>::iterator it=v.begin();it!=v.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
//1.基本使用
void test01(){
vector<int> v; //默认构造
for(int i=0;i<10;i++){
v.push_back(i);
}
printVector(v);
vector<int> v2;
for(int i=20;i>10;i--){
v2.push_back(i);
}
printVector(v2);
cout<<"交换后"<<endl;
v.swap(v2);
printVector(v);
printVector(v2);
}
//2.实际用途
//巧用swap可以收缩内存空间
void test02(){
vector<int> v;
for(int i=0;i<10000;i++){
v.push_back(i);
}
cout<<"v容量:"<<v.capacity()<<endl; //输出1.6w
cout<<"v大小:"<<v.size()<<endl; //输出1w
//重新指定,指定后容量不变
v.resize(3);
cout<<"v容量:"<<v.capacity()<<endl; //输出1.6w
cout<<"v大小:"<<v.size()<<endl; //输出1w
//巧用swap收缩内存
vector<int>(v).swap(v);
cout<<"v容量:"<<v.capacity()<<endl; //输出3
cout<<"v大小:"<<v.size()<<endl; //输出3
}
int main() {
test02();
return 0;
}
总结:swap可以使两个容器互换,达到实用的收缩内存效果
3.2.8 vector预留空间
功能描述:减少vector在动态扩展容量时的扩展次数。
函数原型: reserve(int len);//容器预留len个元素长度,预留位置不初始化,元素不可访问。
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//vector 容器预留空间
void test01(){
vector<int> v; //默认构造
//利用reserve预留空间
v.reserve(100000);
int num = 0; //统计开辟的次数
int *p = NULL;
for(int i=0;i<100000;i++){
v.push_back(i);
if(p != &v[0]){
p = &v[0];
num++;
}
}
//开辟了多少次内存,这里是18
cout<<"num="<<num<<endl;
}
void test02(){
vector<int> v; //默认构造
//利用reserve预留空间
v.reserve(100000);
int num = 0; //统计开辟的次数
int *p = NULL;
for(int i=0;i<100000;i++){
v.push_back(i);
if(p != &v[0]){
p = &v[0];
num++;
}
}
//开辟了多少次内存,加上 reserve预留空间,此时只开辟一次
cout<<"num="<<num<<endl;
}
int main() {
test01();
return 0;
}
3.3 deque容器
3.3.1 deque容器基本概念
3.2.2 dequeue构造函数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//deque 构造函数
void PrintDeque(const deque<int>&d){
//若形参是 const,则迭代器遍历时候需要const_iterator
for(deque<int>::const_iterator it=d.begin();it!=d.end();it++){
//*it=100; 容器中的数据不可修改了
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
deque<int> d1;
for(int i=0;i<10;i++){
d1.push_back(i);
}
PrintDeque(d1);
deque<int> d2(d1.begin(),d1.end());
PrintDeque(d2);
deque<int> d3(10,100); //10个100
PrintDeque(d3);
deque<int> d4(d3); //拷贝构造
PrintDeque(d4);
}
int main() {
test01();
return 0;
}
总结:deque容器和vector容器构造方式几乎一致
3.2.3 deque赋值操作
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//deque 赋值操作
void PrintDeque(const deque<int>&d){
for(deque<int>::const_iterator it=d.begin();it!=d.end();it++){
//*it=100; 容器中的数据不可修改了
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
deque<int> d1;
for(int i=0;i<10;i++){
d1.push_back(i);
}
PrintDeque(d1);
// operator= 赋值
deque<int> d2 = d1;
//assign
deque<int> d3;
d3.assign(d1.begin(),d2.end());
PrintDeque(d3);
//
deque<int> d4;
d4.assign(10,100);
PrintDeque(d4);
}
int main() {
test01();
return 0;
}
3.3.4 deque大小操作
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//deque 容器大小操作
void PrintDeque(const deque<int>&d){
for(deque<int>::const_iterator it=d.begin();it!=d.end();it++){
//*it=100; 容器中的数据不可修改了
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
deque<int> d1;
for(int i=0;i<10;i++){
d1.push_back(i);
}
PrintDeque(d1);
//判断空
if(d1.empty()){
cout<<"d1为空"<<endl;
}else{
//deque没有capacity 概念
cout<<"d1大小:"<<d1.size()<<endl;
}
//重新指定大小
d1.resize(15); //多的填充0
d1.resize(15,1); //多的填充1
}
int main() {
test01();
return 0;
}
3.3.5 deque插入和删除
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//deque 容器插入和删除
void PrintDeque(const deque<int>&d){
for(deque<int>::const_iterator it=d.begin();it!=d.end();it++){
//*it=100; 容器中的数据不可修改了
cout<<*it<<" ";
}
cout<<endl;
}
//两端操作
void test01(){
deque<int> d1;
d1.push_back(10);d1.push_back(20); //尾插
d1.push_front(30);d1.push_front(40); //头插
PrintDeque(d1); //输出 40 30 10 20
d1.pop_back(); //尾删
PrintDeque(d1); //输出 40 30 10
d1.pop_back(); //头删
PrintDeque(d1); //输出 30 10
}
void test02(){
deque<int> d1;
d1.push_back(10);d1.push_back(20);d1.push_front(30);d1.push_front(40);
//输出 40 30 10 20
PrintDeque(d1);
//insert插入
d1.insert(d1.begin(),1000); //变为 1000 40 30 10 20
d1.insert(d1.begin(),2,10000); //变为 10000 10000 1000 40 30 10 20
//按照区间进行插入
deque<int> d2;
d2.push_back(1);d2.push_back(2);d2.push_back(3);
d1.insert(d1.begin(),d2.begin(),de.end());
PrintDeque(d1); //输出 1 2 3 10000 10000 1000 40 30 10 20
}
void test03(){
deque<int> d1;
d1.push_back(10);d1.push_back(20);d1.push_front(30);d1.push_front(40);
//删除
deque<int>::iterator it = d1.begin();
it++;
d1.erase(it);
PrintDeque(d1); //输出 40 10 20
//按区间方式删除
d1.erase(d1.begin(),d1.end()); //等价 d1.clear();
}
int main() {
test01();
return 0;
}
3.3.6 deque数据存取
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//deque 容器数据存取
void PrintDeque(const deque<int>&d){
for(deque<int>::const_iterator it=d.begin();it!=d.end();it++){
//*it=100; 容器中的数据不可修改了
cout<<*it<<" ";
}
cout<<endl;
}
//两端操作
void test01(){
deque<int> d1;
d1.push_back(10);d1.push_back(20); //尾插
d1.push_front(30);d1.push_front(40);d1.push_front(50); //头插
for(int i=0;i<d1.size();i++){
cout<<d[i]<<" ";
}
cout<<endl; //输出 50 40 30 10 20
//通过at访问
cout<<d1.at(0)<<endl;
//访问第一个元素
cout<<d1.front()<<endl;
//访问第二个元素
cout<<d1.back()<<endl;
}
int main() {
test01();
return 0;
}
3.3.7 deque排序
使用sort
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//deque 容器数据存取
void PrintDeque(const deque<int>&d){
for(deque<int>::const_iterator it=d.begin();it!=d.end();it++){
//*it=100; 容器中的数据不可修改了
cout<<*it<<" ";
}
cout<<endl;
}
//两端操作
void test01(){
deque<int> d1;
d1.push_back(10);d1.push_back(20); //尾插
d1.push_front(30);d1.push_front(40);d1.push_front(50); //头插
//排序前 50 40 30 10 20
// 对于支持随机访问的迭代器的容器,都可以利用sort算法直接对其进行排序
sort(d1.begin(),d1.end());
//排序后 默认升序:输出 10 20 30 40 50
PrintDeque(d1);
}
int main() {
test01();
return 0;
}
3.4 stack容器
3.4.1 stack基本概念
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
//栈 stack 容器
void test01(){
//先进后出
stack<int>s;
//入栈
s.push(10); s.push(2); s.push(35); s.push(67);
while(!s.empty()){
//栈不为空 就查看栈顶,并出栈
cout<<"栈顶元素"<<s.top()<<endl;
//出栈
s.pop();
}
cout<<"栈大小:"<<s.size()<<endl;
}
int main() {
test01();
return 0;
}
3.6 queue容器
3.6.1 queue基本概念
3.6.2 常用接口
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// 队列queue 常用接口
class Per{
public:
Per(string n,int a){
this->name = n;
this->age = a;
}
string name;
int age;
};
void test01(){
queue<Per> q; //创建队列
Per p1("王",21); Per p1("李",21); Per p1("张",21);
//入队
q.push(p1); q.push(p2); q.push(p3); q.push(p4);
//只要队列不为空,查看队头,查看队尾,出队
while(!q.empty()){
//查看队头
cout<<"队头:"<< q.front().name<<"年龄:"<<q.front().age<<endl;
//查看队尾
cout<<"队头:"<< q.back().name<<"年龄:"<<q.back().age<<endl;
//出队
q.pop();
}
cout<<"队列大小:"<<q.size()<<endl;
}
int main() {
test01();
return 0;
}
3.7 list容器
3.7.2 list构造函数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// list容器 构造函数
void printList(const list<int> &l){
for(list<int>::const_iterator it=l.begin();it!=l.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
//创建list容器
list<int> L1;
L1.push_back(10);
printList(L1);
//区间方式构造
list<int> L2(L1.begin(),L1.end());
printList(L2);
//拷贝构造
list<int> L3(L2);
//n个elem
list<int> (10,100); //10个100
}
int main() {
test01();
return 0;
}
3.7.3 list赋值和交换
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// list容器 赋值和交换
void printList(const list<int> &l){
for(list<int>::const_iterator it=l.begin();it!=l.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
//创建list容器
list<int> L1;
L1.push_back(10);L1.push_back(25);L1.push_back(523);
list<int> L2;
L2 = L1; //operator= 形式赋值
list<int> L3;
L3.assign(L2.begin(),L2.end()); //assign区间赋值
list<int> L4;
L4.assign(10,200); //10个200
//L4 和 L3 交换
cout<<"交换前:"<<endl;
printList(L3);printList(L4);
L3.swap(L4);
cout<<"交换后:"<<endl;
printList(L3);printList(L4);
}
int main() {
test01();
return 0;
}
3.7.4 list容器大小
3.7.5 list插入和删除
insert,erase中pos参数应为迭代器。elem为元素值。
3.7.6 list 容器的数据存取
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// list容器 赋值和交换
void printList(const list<int> &l){
for(list<int>::const_iterator it=l.begin();it!=l.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
//创建list容器
list<int> L1;
L1.push_back(10);L1.push_back(25);L1.push_back(523);
cout<<"第一个元素:"<<L1.front()<<endl;
cout<<"最后一个元素:"<<L1.back()<<endl;
//list本质是链表,不是连续线性空间存储数据,迭代器也是不支持随机访问的
//验证迭代器是不支持随机访问的
list<int>::iterator it = L1.begin();
it++;
//it = it + 1; //错误 若容器迭代器可以 it = it + 1则支持随机访问
}
int main() {
test01();
return 0;
}
3.7.7 list反转和排序
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// list容器 赋值和交换
void printList(const list<int> &l){
for(list<int>::const_iterator it=l.begin();it!=l.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
bool cmp(int a,int b){
return a>b?true:false;
}
void test01(){
//创建list容器
list<int> L1;
L1.push_back(10);L1.push_back(25);L1.push_back(523);
//反转
L1.reverse();
printList(L1);
//排序,所有不支持随机访问迭代器的容器,不可以使用sort等标准算法
//sort(L1.begin(),L1.end());
//不支持随机访问迭代器的容器,内部会提供对应的一些算法
L1.sort(); //默认升序
printList(L1); // 10 25 523
L1.sort(cmp);
printList(L1); // 523 25 10
}
int main() {
test01();
return 0;
}
3.7.8 排序案例
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// list容器 自定义数据类型排序
class Person{
public:
Person(string n,int a,int h){
this->name = n;
this->age = a;
this->height = h;
}
string name;
int age;
int height;
};
void printList(const list<Person> &l){
for(list<Person>::const_iterator it=l.begin();it!=l.end();it++){
cout<<(*it).name<<" "<<(*it).age<<" "<<(*it).height<<" ";
}
cout<<endl;
}
bool cmp(Person p1,Person p2){
//按照年龄升序
if(p1.age == p2.age){
//年龄相同,按身高降序
return p1.height > p1.height;
}
return p1.age < p2.age;
}
void test01(){
//创建list容器
list<Person> L1;
Person p1("王",28,176);Person p2("李",25,171);Person p3("张",26,175);Person p4("杨",26,173);
L1.push_back(p1); L1.push_back(p2); L1.push_back(p3); L1.push_back(p4);
printList(L1);
cout<<"排序后-----------------"<<endl;
L1.sort(cmp);
printList(L1);
}
int main() {
test01();
return 0;
}
3.8 set/multiset容器
3.8.1 set基本概念
3.8.2 set构造和赋值
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// set容器构造和赋值
void printSet(set<int> &s){
for(set<int>::iterator it=s.begin();it!=s.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
//创建set容器
set<int> s1;
//插入数据 只有insert方式
s1.insert(10); s1.insert(50);s1.insert(30);s1.insert(50);
//遍历容器,
//特点:1.所有元素插入时自动被排序。2.set容器不允许插入重复值
printSet(s1);
//拷贝构造
set<int> s2(s1);
//=赋值
set<int> s3 = s2;
}
int main() {
test01();
return 0;
}
3.8.3 set大小和交换
set<int> s1;
set<int> s2;
s1.swap(s2);
3.8.4 插入和删除
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// set容器构造和赋值
void printSet(set<int> &s){
for(set<int>::iterator it=s.begin();it!=s.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
set<int> s1;
s1.insert(50); s1.insert(10);s1.insert(30);s1.insert(50);
//删除指定位置,传入迭代器
s1.erase(s1.begin()); //删除 10,是排序后的第一个
//删除重载版本
s1.erase(30); //删除30
s1.erase(s1.begin(),s1.end());
}
int main() {
test01();
return 0;
}
3.8.5 set查找和统计
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// set容器构造和赋值
void printSet(set<int> &s){
for(set<int>::iterator it=s.begin();it!=s.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
set<int> s1;
s1.insert(50); s1.insert(10);s1.insert(30);s1.insert(50);
set<int> s1;
set<int>::iterator it = s1.find(30);
if(pos != s1.end())
//找到
}else{ //未找到
}
//统计某个元素个数
s1.count(50); //结果为1。因为set不允许重复,因此count返回只有0或1
int main() {
test01();
return 0;
}
3.8.6 set和multiset区别
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// set和multiset区别
void printSet(set<int> &s){
for(set<int>::iterator it=s.begin();it!=s.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
void test01(){
set<int> s1;
pair<set<int>::iterator,bool> ret = s1.insert(10);
if(ret.second){
//取出bool,此时为真
cout<<"第一次插入成功"<<endl;
}else{
cout<<"第一次插入失败"<<endl;
}
ret = s1.insert(10);
if(ret.second){
//此时为假,插入失败
cout<<"第二次插入成功"<<endl;
}else{
cout<<"第二次插入失败"<<endl;
}
//允许插入重复值
multiset<int> ms;
ms.insert(10); ms.insert(10);
for(multiset<int>::iterator it=ms.begin();it!=ms.end();++it){
cout<<*it<<" ";
}
}
int main() {
test01();
return 0;
}
3.8.7 对组创建
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// pair对组的创建
void test01(){
//第一种方式
pair<string,int>p("tom",20);
cout<<p.first<<" "<<p.second<<endl;
//第二种方式
pair<string,int>p2 = make_pair("jerry",32);
cout<<p2.first<<" "<<p2.second<<endl;
}
int main() {
test01();
return 0;
}
3.8.8 set容器排序
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// set容器的排序 利用仿函数
class MyComp{
public:
//重载()
bool operator()(int v1,int v2){
//让前边数大于后边数,降序
return v1>v2;
}
};
void test01(){
set<int> s1;
s1.insert(10);s1.insert(40);s1.insert(20);s1.insert(50);
for(set<int> s1::iterator it=s1.begin();it!=s1.end();it++){
cout<<*it<<" ";
}
cout<<endl;
//指定排序规则为从大到小,利用仿函数创建容器就指定从大到小
set<int,MyComp> s2;
s2.inseret(10);s2.insert(40);s2.insert(20);s2.insert(50);
for(set<int> s2::iterator it=s2.begin();it!=s2.end();it++){
cout<<*it<<" ";
}
cout<<endl;
}
int main() {
test01();
return 0;
}
set自定义数据类型指定排序规则
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// set容器排序-对自定义数据类型
class Person{
public:
Person(string n,int a){
this->name = n;
this->age = a;
}
string name;
int age;
};
class comparePerson{
public:
bool operator()(const Person&p1,const Person&p2){
//按照年龄降序
return p1.age>p2.age;
}
};
void test01(){
//默认从小到大,自定义数据类型都会指定排序规则
set<Person,comparePerson> s1;
Person p1("刘",23);Person p2("关",25);Person p3("张",28);
s1.insert(p1);s1.insert(p2);s1.insert(p3);
for(set<Person,comparePerson>::iterator it=s1.begin();it!=s1.end();it++){
cout<<(*it).name<<" "<<(*it).age<<" ";
}
cout<<endl;
}
int main() {
test01();
return 0;
}
3.9 map和multimap容器
3.9.1 map基本概念
3.9.2 map构造和赋值
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// map容器 构造和赋值
void printMap(map<int,int>&mp){
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it){
cout<<"key:"<<(*it).first<<" val:"<<(*it).second<<endl;
}
}
void test01(){
//默认按照key升序排序
map<int,int> mp;
mp.insert(pair<int,int>(1,20));
mp.insert(pair<int,int>(5,40));
mp.insert(pair<int,int>(2,30));
printMap(mp);
//赋值
map<int,int> mp1 = mp;
//拷贝构造
map<int,int> mp2(mp);
}
int main() {
test01();
return 0;
}
3.9.2 map大小和交换
3.9.4 map插入和删除
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// map容器 插入和删除
void printMap(map<int,int>&mp){
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it){
cout<<"key:"<<(*it).first<<" val:"<<(*it).second<<endl;
}
}
void test01(){
//默认按照key升序排序
map<int,int> mp;
//插入
// 第一种
mp.insert(pair<int,int>(1,20));
// 第二种
mp.insert(make_pair(2,54));
//第三种--不建议 因为此时若输出 mp[4],会输出0
mp[3] = 46;
//删除
mp.erase(mp.begin());
mp.erase(3); //按照key删除
mp.erase(mp.begin(),mp.end());
}
int main() {
test01();
return 0;
}
3.9.5 map查找和统计
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// map容器 插入和删除
void printMap(map<int,int>&mp){
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it){
cout<<"key:"<<(*it).first<<" val:"<<(*it).second<<endl;
}
}
void test01(){
//默认按照key升序排序
map<int,int> mp;
//插入
mp.insert(pair<int,int>(1,20));
mp.insert(make_pair(2,54));
//查找
map<int,int>::iterator pos = mp.find(2);
if(pos != mp.end()){
//找到
cout<<(*pos).first<<" "<<(*pos).second<<endl;
}
//统计 结果只能是0或1
int c = mp.count(2);
}
int main() {
test01();
return 0;
}
3.9.6 map排序
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// map容器 排序规则
class comp{
public:
bool operator()(int v1,int v2){
//降序
return v1>v2;
}
};
void test01(){
//默认按照key升序排序
map<int,int,comp> mp;
//插入
mp.insert(pair<int,int>(1,20));
mp.insert(make_pair(2,54));
mp.insert(make_pair(5,54));
for(map<int,int>::iterator it=mp.begin();it!=mp.end();++it){
cout<<"key:"<<(*it).first<<" val:"<<(*it).second<<endl;
}
}
int main() {
test01();
return 0;
}
4 STL-函数对象
4.1 函数对象
4.1.1 函数对象概念
4.1.2 函数对象使用
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// 函数对象--仿函数
//1、函数对象使用时候,可以像普通函数一样调用,可以有参数,可以有返回值
class Myadd{
public:
int operator()(int v1,int v2){
return v1+v2;
}
};
void test01(){
Myadd m1;
cout<<m1(10,20);
}
//2.函数对象超出普通函数概念,函数对象可以有自己状态
class Myprint(){
public:
Myprint(){
this->count=0;
}
void operator()(string name){
cout<<name<<endl;
count++;
}
int count; //内部自己状态
}
void test02(){
Myprint m2;
m2("hello");m2("hello");
cout<<"count调用次数:"<<m2.count<<endl;
}
//3、函数对象可以作为参数传递
void doPrint(Myprint &mp,string test){
mp(test);
}
void test03(){
Myprint m2;
doPrint(m2,"hello");
}
int main() {
test01();
return 0;
}
4.2 谓词
4.2.1 谓词概念
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// 仿函数 返回值是bool类型,称为谓词
//一元谓词
class GrFive{
public:
bool operator()(int v){
return v>5;
}
};
void test01(){
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
//查找容器中有无大于5的数
vector<int>::iterator it = find_if(v.begin(),v.end(),GrFive());
if(it==v.end()){
//未找到
}
}
int main() {
test01();
return 0;
}
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// 仿函数 返回值是bool类型,称为谓词
//二谓词
class Comp{
public:
bool operator()(int v1,int v2){
return v1>v2; //降序
}
};
void test01(){
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
sort(v.begin(),v.end());
for(int i=0;i<10;i++){
cout<<v[i]<<" ";
}
cout<<endl;
//使用函数对象 改变算法策略 改变排序规则为从大到小
sort(v.begin(),v.end(),Comp());
for(int i=0;i<10;i++){
cout<<v[i]<<" ";
}
}
int main() {
test01();
return 0;
}
4.3 内建函数对象
4.3.1 内建函数对象意义
4.3.2 算术仿函数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// 内建函数对象 算术仿函数
// negate 一元仿函数 取反仿函数
void test01(){
negate<int> n;
cout<<n(-50)<<endl;
}
// plus二元仿函数
void test02(){
plus<int> p;
cout<<p(3,56)<<endl;
}
int main() {
test02();
return 0;
}
4.3.3 关系仿函数
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
// 内建函数对象 关系仿函数
// 大于 greater
class Comp{
public:
bool operator()(int v1,int v2){
return v1>v2; //降序
}
};
void test01(){
vector<int> v;
v.push_back(2);v.push_back(25);v.push_back(12);v.push_back(22);
for(auto vv : v){
cout<<vv<<" ";
}
cout<<endl;
//降序,使用内建函数
sort(v.begin(),v.end(),greater<int>());
for(auto vv : v){
cout<<vv<<" ";
}
}
int main() {
test01();
return 0;
}
4.3.4 逻辑仿函数
基本用不到