C++ STL

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 逻辑仿函数

在这里插入图片描述

基本用不到

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值