近万字带你了解“c++“STL中的各种容器
Posted gfxr1212
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了近万字带你了解“c++“STL中的各种容器相关的知识,希望对你有一定的参考价值。
目录
1.array容器
包含头文件#include<array>才能使用
简单来说他就是一个数组 知识c++中把他封装成一个类 这样可以直接使用
使用方法是array<类型,长度>
我们自己实现一个myarray带大家了解一下过程
#include<iostream>
#include<array>
using namespace std;
template<class _Ty,size_t size>
class myarray
public:
myarray()
//由给定的长度类型构造出来
memory = new _Ty[size];
//这里要返回引用 表示[]表示调用类中的数据
_Ty& operator[](int index)
return memory[index];
_Ty front()
return memory[0];
_Ty back()
return memory[size - 1];
_Ty at(int index)
return memory[index];
public:
//迭代器可以理解为就是一个指针
class iterator
public:
iterator(_Ty* pmove = nullptr) :pmove(pmove) ;
//重载迭代器地址赋值=
void operator=(iterator object)
this->pmove = object.pmove;
bool operator!=(iterator object)
return this->pmove != object.pmove;
iterator operator++(int)//里面有int为前置
pmove++;
return (*this);
_Ty operator*()
return *pmove;
protected:
_Ty* pmove;
;
public:
//使用这个函数时表示指向数组首地址
iterator begin()
return iterator(memory + 0);//调用构造函数去赋值
iterator end()
return iterator(memory + size);//调用构造函数去赋值
protected:
_Ty* memory;
;
int main()
myarray<int, 3>k;
//因为我们这里简单实现没有在构造函数里面写初始化参数列表
for (int i = 0; i < 3; i++)
//相当于调用重载函数[]
k[i] = i;
myarray<int, 3>::iterator iter;
for ( iter= k.begin(); iter != k.end(); iter++)
cout << *iter;//*调用*的重载函数
return 0;
2.vector容器
理解就是想当于一个长度可以变换的数组
包含头文件#include<vector>才可以使用
使用方法:
vector<类型>或者vector<类型>变量名(长度)//后置可以当一个以为数组去简单赋值
vector<int> testv;
for (int i = 0; i < 5; i++)
testv.push_back(i);
vector<int>testv2(5);
for (int i = 0; i < 5; i++)
testv2[i] = i;
所以一般在使用动态数组,有个习惯
带长度创建的vector 一般都是用下标法使用
不带长度的vector,采用成员函数的方式操作
遍历vector容器和数组是一样的因为容器里面都包含了iterator(迭代器) 可以去实现遍历
vector 和 array镶嵌使用
No.1 array与array嵌套
No.2 vecotr与vecotr嵌套
No.3 array与vector互相嵌套
array和array
array<array<int, 3>, 2> test;
//就相当一个二行每行有三个元素的数组
//理解把array<int,3>看成一个类型
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
test[i][j] = i;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 3; j++)
cout << test[i][j] << " ";
cout << endl;
array和vector
array<vector<int>, 3>test;
//相当于有一个三个vector<int>数组
for (int i = 0; i < 3; i++)
test[i].push_back(5);
test[i].push_back(6);
test[1].push_back(1);
for (int i = 0; i < 3; i++)
for (int j = 0; j < test[i].size(); j++)
cout << test[i][j]<<" ";
cout << endl;
vector和vector
vector<vector<int>>test(3);
//有长度的表示有3个vector<int>
//就等效于二维数组有三行但是每行的列数是可以变化的
for (int i = 0; i < test.size(); i++)
test[i].push_back(5);
test[i].push_back(6);
test[2].push_back(5);
for (int i = 0; i < test.size(); i++)
for (int j = 0; j < test[i].size(); j++)
cout << test[i][j] << " ";
cout << endl;
cout << endl;
4.链表容器(list)是一个库封装好的一个双向链表
里面包含的一些常使用函数
push_back()
pop_back();
push_front();
pop_front();
size();
empty();
erase+find
insert+
sort();
void printflist(list<_Ty> data)
for (auto v : data)
cout << v << endl;
int main()
list<string> testlist;
testlist.push_back("fsdj");//相当于尾插
testlist.push_back("erowe");
testlist.push_front("erewe");//头插
testlist.push_back("a");
testlist.sort();//默认是小到大的//这里就是字母排序
cout << "less<string>()排序准则" << endl;
printflist(testlist);
//大到小的排序准则
cout << "greater<string>()排序准则" << endl;
testlist.sort(greater<string>());
printflist(testlist);
return 0;
链表存储自定义类型:
主要了解排序准则
1.靠类中重载的方式调用括号来调用函数接口
2.直接写函数来调用接口
#include<iostream>
#include<vector>
#include<array>
#include<list>
#include<string>
using namespace std;
template<class _Ty>
void printflist(list<_Ty> data)
for (auto v : data)
cout << v;
class MM
public:
MM(string name, int year) :name(name), year(year) ;
//重载输出就可以打印对象成员
friend ostream& operator<<(ostream& out, MM& object)
out << object.name << " " << object.year << endl;
return out;
//获取对象的年龄
int& getyear()
return this->year;
string& getname()
return this->name;
protected:
string name;
int year;
;
//重写排序准则仿函数
class compareyear
//重载括号
public://要共有类 不然不能用()代表函数来提供接口
bool operator()(MM object1, MM object2)
return object1.getyear() > object2.getyear();//年龄大到小的准则
;
//
bool comparesname(MM object1, MM object2)
return object1.getname() < object2.getname();
int main()
list<MM>test1;
test1.push_back(MM("张三", 18));
test1.push_back(MM("李四", 28));
test1.push_back(MM("王五", 78));
cout << "按年龄大到小的排序准则" << endl;
test1.sort(compareyear());
//解释这个compareyear()这里括号就相当于调用了里面类中的函数
//提供一个接口
printflist(test1);
test1.sort(comparesname);//提供一个函数 提供一个接口
cout << "按姓名小到大的排序准则" << endl;
printflist(test1);//按姓名排序
return 0;
5.priority_queue: 优先队列
按照特定数据特定的标准排序的队列
接下来用vector写一个容器中的优先队列带大家了解一下基础操作
//
#include<iostream>
#include<vector>
#include<array>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
template<class _Ty,class _contain=vector<_Ty>,class _pr=less<_Ty>>
//分别为类型 容器 排序准则
class priority_queue
public:
priority_queue() = default;//默认的构造函数
void push(_Ty data)
mem.push_back(data);
sort(mem.begin(), mem.end(), _pr());//容器排序
void pop()
mem.erase(mem.begin());//出队列
const _Ty& top()
return mem.begin();
bool empty()const
return mem.empty();
int size()const
return mem.size();
protected:
_contain mem;//就是容器
;
int main()
priority_queue<int> test1;
for (int i = 10; i >= 0; i--)
test1.push(i);
cout << test1.size() << endl;
test1.pop();
cout << test1.size();
6.map和multimap
No.1 map是 映射,就是一种对应关系(数组:下表与值对应)
1.1 排序性 (按照键的排序)
1.2 唯一性 (按照键的唯一性) 相同键的时候,不做插入
1.3 存储的数据是一个数对类型: pair<Type1,type2>;
first:键 second:值
map<类型,类型,排序准则(默认缺省为小到大)>
排序准则是按键值来的
#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
int main()
map<int, string> test;
//下标插入
test[1] = "sdfj";
test[-1] = "oiwer";
//用pair类构造
test.insert(pair<int, string>(6, "sfewr"));
//insert插入 用make_pair构造
test.insert(make_pair(5, "sfd"));
for (map<int, string>::iterator iter = test.begin(); iter != test.end(); iter++)
cout << iter->first << " " << iter->second << endl;
//分别为打印键和打印值
//存在默认的排序函数
return 0;
用map去操作自定义类型主要:是重写排序函数
排序准则下的比较要加const修饰安全起见防止被修改里面的值
#include<iostream>
#include<map>
using namespace std;
class Boy
public:
friend ostream& operator<< (ostream& out, Boy one)
out << one.getAge() << " " << one.getName();
return out;
Boy() = default;
Boy(string name, int age) :name(name), age(age)
string getName()const
return name;
int getAge()const
//作为排序准则比较要加const
因为map内部是一个const对象
return age;
protected:
string name;
int age;
;
class MM
public:
MM() = default;
MM(string name, int age) :name(name), age(age)
friend ostream& operator<< (ostream & out, MM one)
out << one.getAge() << " " << one.getName();
return out;
string getName()
return name;
int getAge()
return age;
protected:
string name;
int age;
;
class LessByAge
public://重写的排序准则要加const
bool operator()(const Boy& one, const Boy& two)const
return one.getAge() < two.getAge();
;
int main()
map<Boy, MM, LessByAge> bm;
bm[Boy("张三", 28)] = MM("小芳", 28);
bm[Boy("李四", 18)] = MM("小美", 28);
bm[Boy("王五", 38)] = MM("小丽", 18);
bm.insert(make_pair(Boy("李六",19) ,MM("燕子", 19)));
bm.insert(pair<Boy, MM>( Boy("老七",15),MM( "颗粒", 17 )));
for (auto v : bm) //v pair<Boy,MM>
cout << v.first << "配对" << v.second << endl;
return 0;
注意;
以什么为排序准那么这个排序准则中的数字就不能相同
如:这里中Boy类型不能用相同年龄的有就会取第一个后面一个不取
multimap
//多重映射: 只具有排序性
//键是允许重复,所以不存在下标法访问
multimap<int,string> test;
//因为multimap可以存在相同的键值所有这样是错的
test[1] = "kk";
插入的方法:
test.insert(make_pair(5, "ksdf"));
test.insert(pair<int, string>(5, "fsd"));
for (map<int, string>::iterator iter = test.begin(); iter != test.end(); iter++)
cout << iter->first << " " << iter->second << endl;
7.set和multiset
No.1 set:集合 用来存储数据
1.1 有序性,默认从小到大
1.2 唯一性,不重复
set<int> test = 8,5,6,2,2,4 ;
for (set<int>::iterator iter = test.begin(); iter != test.end(); iter++)
cout << *iter << " ";
输出后是一个2 4 5 6 8
set<int,greater<int>> test = 8,5,6,2,2,4 ;
for (set<int>::iterator iter = test.begin(); iter != test.end(); iter++)
cout << *iter << " ";
输出结果是8 6 5 4 2
这里的排序准则直接写个对象greater<int>
是因为在调用set里面排序的时候会自动去调用对象里面的函数
multiset
只具有排序的功能可以出现相同的数字
multiset<int> test = 1,1,2,2,3,5 ;
for (set<int>::iterator iter = test.begin(); iter != test.end(); iter++)
cout << *iter << " ";
输出就是1 1 2 2 3 5
multiset<int,greater<int>> test = 1,1,2,2,3,5 ;
for (set<int>::iterator iter = test.begin(); iter != test.end(); iter++)
cout << *iter << " ";
输出就是5 3 2 2 1 1
以上是关于近万字带你了解“c++“STL中的各种容器的主要内容,如果未能解决你的问题,请参考以下文章