IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> Day15: C++之STL容器(3/3) -> 正文阅读

[C++知识库]Day15: C++之STL容器(3/3)

一、集合set

头文件<set>

1.特性:

????????①数据自带排序②没有重复(数据的唯一性)

2.基本操作:

????????①创建(第一个参数是存储数据的类型,第二个是排序准则)

	set<int> setData;					//默认方式 从小到大
	set<int, less<int>> setData2;		//和默认方式一样
	set<int, greater<int>> setData3;	//从大到小

????????②插入:insert(data)

setData.insert(temp);

????????③迭代器遍历

	for (set<int>::iterator iter = setData.begin(); iter != setData.end(); iter++) 
	{
		cout << *iter << " ";
	}

3.对于自定义类型数据的处理:

????????核心问题:重载?第一行的less<····>是作为第二个的默认参数(下为set原型)

?而less即为从小到大? 所以我们需要重载<号 (其余同理) (注:一定要是常属性参数+常函数)

class wbm
{
public:
	wbm(string name,int age):name(name),age(age){}
	bool operator<(const wbm &temp)const
	{
		return name < temp.name;
	}
	void print()
	{
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
void test_wbm_set()
{
	wbm w1("wbm1", 11);
	wbm w2("wbm2", 22);
	wbm w5("wbm5", 55);
	wbm w4("wbm4", 44);
	wbm w3("wbm3", 33);
	wbm temptest("wbm3", 99);
	set<wbm> wbmset = { w1,w2,w3,w4,w5,temptest };
	for (auto v : wbmset)
	{
		v.print();
	}
}

输出结果:(很显然,temptest没有被插入进去)->查重标准是按照重载写的<准则(按照name进行比较的。

?二、多重集合multiset

1.特性:

????????只具有排序功能,不具有去重功能

2.写法同set

????????(不同点在于,multiset仅排序)

void testmultiset()
{
	multiset<int> mulData;
	for (int i = 0; i < 10; i++) 
	{
		mulData.insert(rand() % 10);
		//rand()%26+'A';
		//rand()%26+'a';
	}
	for (auto v : mulData) 
	{
		cout << v << " ";
	}
	cout << endl;
}

输出结果:0 1 2 4 4 4 7 8 8 9?

三、二进制集合bitset

头文件????????????????????????#include<bitset>

1.特性:(常用于二进制操作)

????????管理二进制的容器,不需要传类型(只需要传一个长度->代表有多少个二进制位)

2.常见功能

????????(详见F1微软在线文档,在网安和底层开发会很有用。)

3.简单实例:?

????????①两种构造方式:

? ? ? ? ? ? ? ? ? ? ? 以字符串的形式就是直接原封不动的去掉引号,变成二进制

? ? ? ? ? ? ? ? ? ? ? 以传入一个整数的形式,就是将该整数(十进制)转化为二进制再保存到容器中。

? ? ? ? ②flip():1和0的反转(~)? ?all():检测每一个位是否都是1 ????????any():检测是否有位含1?

void testmultiset()
{
	//多个二进制位
	bitset<8> bData("11110000");
	cout << bData << endl;
	bData.flip();    //等效于~
	cout << bData << endl;
	cout << bData.all() << endl;
	cout << bData.any() << endl;
	cout << bData.size() << endl;
	cout << bData.none() << endl;
	bitset<8> num(7);			//将7转化为二进制的形式保存在bitset的容器中。
	cout << num << endl;
}

?输出:

11110000
00001111
0
1
8
0
00000111

?四、映射map

1.map中存放pair数据类型

????????????????->称为数对类型(将两个数据绑定到一起)

? ? ? ? ? ? ? ? ?实际上就是一个两个待实例化的模板结构体

? ? ? ? ? ? ? ? 访问方式:m_pair.first? ? m_pair.second 分别访问第一二个绑定的元素

template <class _Ty1, class _Ty2>
struct MyPair 
{
	_Ty1 first;
	_Ty2 second;
	MyPair(_Ty1 first, _Ty2 second) :first(first), second(second) {}
};
//map存储的数据是一个数对类型
void testPair() 
{
	pair<int, string> pData(1, "string");
	MyPair<int, string> myPData(1, "string");
	cout << pData.first << " " << pData.second << endl;
}

2.map的特性

? ? ? ? ①自带排序,默认是从小到大

? ? ? ? ②数据唯一性

3.基本操作

? ? ? ? ①插入:

? ? ? ? ? ? ? ? 方式一:insert一个数对类型(两个数值,first是键,second是值)

map<int,string> mapData;
mapData.insert(pair<int,string>(1,"string"));

? ? ? ? ? ? ? ? 方式二:insert通过一个make_pair函数构建

map<int,string> mapData;
mapData.insert(make_pair<int,string>(3,"string3"));

? ? ? ? ? ? ? ? 方式三单映射中,可以直接采用数组下标的方式进行插入

map<int,string> mapData;
mapData[-1]=string("string-1");

?方式三的代码等效于:

? ? ? ? mapData.insert(pair<int,string>(-1,"string-1"));

?注:相同的键,是采用覆盖的方式(保留最后一次更新的值)

? ? ? ? ?②遍历:

? ? ? ? ? ? ? ? 方式一:迭代器遍历

? ? ? ? ? ? ? ? ? ? ? ? (注:这里的*iter是pair数对类型。)

for(auto iter=mapData.begin();iter!=mapData.end();iter++)
{
    cout<<iter->first<<" "<<iter->second<<endl; 
    //*iter指的是pair类型。
}

? ? ? ? ? ? ? ? 方式二:

for(auto v:mapData)
{
    cout<<v.first<<" "<<v.second<<endl;
}

? ? ? ? ?③删除erase():

? ? ? ? ? ? ? ? ? ? ?传入参数(是需要删除值对应的键)

mapData.erase(1);

? ? ? ? ④其他创建方式(有一个默认比较准则参数)

map<int,string> mapData;
map<int ,string,less<int>> mapData1; //此创建方式,等同于第一行,从小到大。
map<int,string,greater<int>>mapData2; //从大到小

? ? ? ? ⑤处理自定义数据类型:

?????????核心还是写重载函数(默认是按照键的某个属性进行比较),所以应该当键是自定义数据类型的时候,需要对键进行重载,若是用的默认的less<>比较准则,那么重载的就应该是<号

? ? ? ? (需要默认的构造函数,print()成员函数需要是const类型)

class MM
{
public:
	MM() = default;
	MM(string name, int age) :name(name), age(age) {}
	void print() const
	{
		cout << name << "\t" << age << endl;
	}
	bool operator<(const MM& object)const 
	{
		return this->name < object.name;
	}
protected:
	string name;
	int age;
};
class Boy
{
public:
	Boy() = default;
	Boy(string name, int age) :name(name), age(age) {}
	void print() const
	{
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
void testUserData() 
{
	map<MM, Boy> mbData;
	mbData[MM("小美", 19)] = Boy("小张", 29);
	mbData[MM("小美", 19)].print();
	mbData[MM("小丽", 20)] = Boy("小明", 18);
	cout << "配对信息:" << endl;
	for (auto v : mbData) 
	{
		//容器管理自定义类型数据
		//v:pair<MM,Boy>
		//v.frist:MM
		//v.second:Boy
		v.first.print();
		v.second.print();
	}
}

?4.应用:

????????更好管理资源

?????????????????例: 在加载图片资源的时候,就直接用img[键]去对应相应的资源即可。(相比数组来说,这个下标是没有任何要求。)

#include<grapghic.h>
map<string,IMAGE*> ima;
img["墙"]=new IMAGE;
img["路"]=new IMAGE;
putimage(0,0,img["墙"]);
putimage(0,0,img["路"]);

? 五、多重映射multimap

1.特性:

????????多重映射,没有什么限制,什么样对应关系都可以插入到映射中,因为存在相同的键,所以不能采用下标法

2.基本操作

? ? ? ? 基本同单映射,除了不能用下标法。

????????????????(注:find函数找到就返回,即返回找到的第一个)

void testmultimap()
{
	//多重映射,没有什么限制,什么样对应关系都可以插入到映射中
	//因为存在相同的键,所以不能采用下标法
	multimap<int, string>  mulData;
	mulData.insert(pair<int, string>(1, "string"));
	mulData.insert(pair<int, string>(12, "string1"));
	mulData.insert(pair<int, string>(2, "string"));
	mulData.insert(pair<int, string>(3, "string"));
	mulData.insert(make_pair<int, string>(3, "string"));
	for (auto v : mulData)
	{
		cout << v.first << "\t" << v.second << endl;
	}
}

输出:

1 ? ? ? string
2 ? ? ? string
3 ? ? ? string
3 ? ? ? string
12 ? ? ?string1

六、 initializer_list

头文件:#include <initializer_list>

?1.引入:

????????像这样的容器,初始化由后面的给的数据决定,构造函数的写法原理?

?2.利用:

????????initializer_list对象(迭代器)可以存储大括号内的所有数据,并且可以一一赋值给容器中,对应的位置

? ? ? ? ? ? ? ? 样例代码:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ①写一个类来简单模仿其实现的原理

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ②写一个函数来简单模仿传入多个参数的情况。

#include <array>
#include <list>
#include <vector>
#include <iostream>
#include <initializer_list>
using namespace std;
class MM
{
public:
	MM(string a, string b, string c) :a(a), b(b), c(c) {}
	MM(const initializer_list<string>& list)
	{
		for (auto iter = list.begin(); iter != list.end(); iter++)
		{
			cout << *iter << endl;
		}
	}
protected:
	string a;
	string b;
	string c;
};
void print(initializer_list<int> list)
{
	for (auto iter = list.begin(); iter != list.end(); iter++)
	{
		cout << *iter << " ";
	}
	cout << endl;
}

int main()
{
	array<int, 3> arrData = { 1,2,3 };
	vector<int> vecData1 = { 1,2,3,4 };
	vector<int> vecData2 = { 1,2,3,4,5 };
	MM mm1 = { "string1","string2","string3" };
	MM mm2 = { "string1" };
	MM mm3 = { "string1","string2" };
	initializer_list<int> listOne = { 1,2,3,4,5 };
	initializer_list<int> listTwo = { 1,2,3 };
	print({ 1 });
	print({ 1,2 });
	print({ 1,2,3,4 });
	print({ 1,2,3,4,5 });
	return 0;
}

七、元组tuple容器

#include<tuple>

1.特性:

????????把任何类型的一系列数据当做一组来处理+自动增长

2.创建方式:

//方式一:
tuple<string,int,int,string> wbmInfo={"bmw",18,1001,"23123"};
//方式二:
tuple<double,double,double>wbmscore=make_tuple(99,22,33);
//方式三:
tuple<string,string>value=forward_as_tuple("阿杰","阿明");

以后结构体数组的偷懒写法:

tuple<string,int,int,string> array[3];

?3.访问数据

? ? ? ? 方式一:get方法

????????????????(不能用for循环,必须是常量)

tuple<string,int,int,string> wbmInfo={"BMW",18,1001,"2312"};
//get方法,不能用for循环
cout<<get<0>(wbmInfo)<<"\t";
cout<<get<1>(wbmInfo)<<"\t";
cout<<get<2>(wbmInfo)<<"\t";
cout<<get<3>(wbmInfo)<<"\t";

? ? ? ? 方式二:tie方法

? ? ? ? ? ? ? ? (有点类似于流操作)

tuple<string,int,int,string> wbmInfo={"BMW",18,1001,"2312"};
//tie方式访问数据
string name;
int age;
int num;
string tel;
tie(name,age,num,tel)=wbmInfo;
cout<<name<<"\t"<<age<<"\t"<<num<<"\t"<<tel<<endl;

4.其他操作:

? ? ? ? 将两个tuple连接起来: tuple_cat(参数1,参数2)

tuple<string,int,int,string> wbmInfo={"bmw",18,1001,"23123"};
tuple<double,double,double>wbmscore=make_tuple(99,22,33);
auto res=tuple_cat(wbmInfo,wbmscore);

八、了解部分(折叠参数)

//...Args代表一个参数包
//1.如何通过参数包定义变量 Args ...args?
//2.如何使用参数包?? ?args... one

/*参数包的展开:
?? ?1.递归的方式,自动做一个参数包的剥离过程
?? ?2.采用列表方式进行剥离参数*/

方式一:递归展开实现代码

#include<iostream>
using namespace std;

//递归终止函数
template <class _Ty>
void print(_Ty data)
{
	cout << data<<endl;
}

template <class _Ty,class ...Args>   
void print(_Ty data,Args ...args)
{
	cout << data << "\t";
	print(args...);//递归的方式,自身调用自身。
}

int main()
{	
	print(1, 2, 3, 4, "string", 12.3);

	return 0;
}

?方式二:采用列表(可增长)or数组方式进行剥离参数

template <class _Ty, class ...Args>
void printdata(_Ty data)
{
	cout << data << "\t";
}
template<class ...Args>
void printArgs(Args ...args)
{
	//(printdata(args),0)  这是一个逗号表达式,返回的是最后一个式子的值
	initializer_list<int>{(printdata(args), 0)...};
	//也可以用数组做 等效于 
	//int array[]={(printdata(args), 0)...};
	cout << endl;
 }

int main()
{	
	printArgs(1, 2, 3, 4, "string", 12.3);

	return 0;
}

printdata()是中间解析函数,负责展开打印。列表数据重复调用,(,)逗号表达式,先运行printdata再将0赋值给列表。...每次调用都会剥离分离1个出来。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-25 17:54:42  更:2022-06-25 17:55:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:46:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码