C++ STL

embedded/2024/10/18 0:36:12/

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';		//3string str4;str4.assign("hell");	//4string str5;str5.assign("hello c++",4);	//5string str6;str6.assign(str5);	//6string 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 += ':';			//2string str2 = "lol dnf";str1 += str2;			//3string str3 = "I";str3.append(" love");	//4// I love gamestr3.append("game ab",4);	//5 前4个拼接到str3//I love game lol dnfstr3.append(str2);//I love game lol dnf lolstr3.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;//通过atfor(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 //输出 h111ellocout<<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);//输出zhangsancout<<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);//assignvector<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;	//16cout<<"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_iteratorfor(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;//assigndeque<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个elemlist<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 523L1.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);	//删除30s1.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 逻辑仿函数

在这里插入图片描述

基本用不到


http://www.ppmy.cn/embedded/33001.html

相关文章

Rust web简单实战

一、使用async搭建简单的web服务 1、修改cargo.toml文件添加依赖 [dependencies] futures "0.3" tokio { version "1", features ["full"] } [dependencies.async-std] version "1.6" features ["attributes"]2、搭…

Java八股文3

3.垃圾回收 1.对象什么时候可以被垃圾器回收 1.垃圾回收的概念 为了让程序员更专注于代码的实现&#xff0c;而不用过多的考虑内存释放的问题&#xff0c;所以&#xff0c; 在Java语言中&#xff0c;有了自动的垃圾回收机制&#xff0c;也就是我们熟悉的GC(Garbage Collection)…

数据结构之二叉树

片头 嗨&#xff01;小伙伴们&#xff0c;大家好&#xff0c;今天我们来学习二叉树这种数据结构&#xff0c;学习二叉树之前&#xff0c;我们先了解一下树的概念做个铺垫&#xff0c;Ready Go ! ! ! 一、树 1. 树概念及结构 树是一种非线性的数据结构&#xff0c;它是由n&am…

如何学习 Unreal Engine

学习Unreal Engine&#xff08;简称UE&#xff09;&#xff0c;尤其是最新的UE5&#xff0c;是一项复杂但值得的任务&#xff0c;因为它是游戏开发和实时3D内容创建的强大工具。以下是一些建议来帮助您开始学习Unreal Engine&#xff1a; 1. **了解基础知识**&#xff1a;在深…

JAVA设计模式

**************************************************************************************************************************************************************************** 1、设计模式概述 【1】前辈们对代码开发经验的总结&#xff0c;解决问题的套路。是用来提…

17 大数据定制篇-shell编程

第 17 章大数据定制篇-Shell 编程 17.1 为什么要学习 Shell 编程 Linux 运维工程师在进行服务器集群管理时&#xff0c;需要编写 Shell 程序来进行服务器管理。 对于 JavaEE 和 Python 程序员来说&#xff0c;工作的需要&#xff0c;你的老大会要求你编写一些 Shell 脚本进行…

第十篇:深入文件夹:Python中的文件管理和自动化技术

深入文件夹&#xff1a;Python中的文件管理和自动化技术 1 文件系统基础操作 在今天的技术博客中&#xff0c;我们将深入探讨Python中的文件系统基础操作。文件系统对于任何操作系统都是不可或缺的组成部分&#xff0c;它管理着数据的存储、检索以及维护。Python通过其标准库中…

【leetcode】DFS递归题目总结

DFS&#xff08;深度优先搜索&#xff09; 深度优先搜索是一种用于遍历或搜索树或图的算法&#xff0c;其基本思路是从起始节点开始&#xff0c;沿着一条路径一直走到底&#xff0c;直到无法再走下去为止&#xff0c;然后回溯到上一个节点&#xff0c;继续走到另外一个路径&…