一、string字符串容器
#include <iostream>
using namespace std;
int main()
{
string name;
name = "hello";
string str(10,'w');
cout << str << endl;
name = "hello world";
string sub1(name,0,5);
cout << sub1 << endl;4
string sub2("www.hqyj.com");
cout << sub2 << endl;
string sub3(sub2.begin() + 4,sub2.begin() + 8);
cout << sub3 << endl;
string str3 = "hello world";
-----------------------------------------------------------------------------------------------
for(string::reverse_iterator it = str3.rbegin(); it != str3.rend(); ++it)
{
cout << *it << " ";
}
cout << endl;
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
------------------------------------------------------------------
for(char s : str3)
{
cout << s << " ";
}
cout << endl;
cout << str3.size() << endl;
cout << str3.max_size() << endl;
string str5;
for(int i = 0; i < 20; i++)
{
cout << "str5的有效的字符个数:" << str5.size() << "str5的有效的空间大小" << str5.capacity() << endl;
str5.push_back('a');
}
string str6 = "hello";
cout << str6.append("world") << endl;
cout << str6.replace(0,5,"Big") << endl;
string str7 = "1314";
cout << stoi(str7) + 100 << endl;
return 0;
}
二、vector容器
ector容器:(单向开口的连续内存空间)
--------------------
vector与array无乎是一样的,连续的存储结构,
两者的唯一的区别在于在空间上的灵活,
数组需要提前指定长度,不量确定了就不能发生改变了,
比较死板,不够灵活。
----------------------------------------
vector容器是动态空间,随着元素的加入,
它的内部机制会自动扩充空间以容纳新的元素。
vector中的默认的空间配置策略是2倍进行扩容的。
---------------------------------------------------------------
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
for(int i = 0; i < 20; i++)
{
cout << "vector中的有效元素个数:" << v.size() << " ,vector的有效空间大小" << v.capacity() << endl;
v.push_back(rand() % 100 + 1);
}
for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
for(int k : v)
{
cout << k << " ";
}
cout << endl;
for(int i = 0; i < v.size();i++)
{
cout << v[i] << " ";
}
cout << endl;
return 0;
}
迭代器非法化(迭代器失效问题)
--------------------------------------------
通过迭代器解引用之后找到的值并非原来的值,
因为插入或擦除之后该地址上的元素发生了移动,
通过迭代器解引用后是不能得到与之前的值相同的内容。
---------------------------------
解决方法:
-------------
使用insert或erase时,使用返回值更新一下迭代器
-------------------------------------------
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
for (int i = 0; i < 20; i++)
{
cout << "vector中的有效元素个数:" << v.size() << " ,vector的有效空间大小" << v.capacity() << endl;
v.push_back(rand() % 100 + 1);
}
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
for (int k : v)
{
cout << k << " ";
}
cout << endl;
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
for (auto it = v.begin(); it != v.end(); ++it)
{
if (*it % 2 == 0)
{
it = v.insert(it, 88);
it++;
}
}
for (int k : v)
{
cout << k << " ";
}
cout << endl;
cout << "---------------------------------------" << endl;
for (auto it = v.begin(); it != v.end();)
{
if (*it % 2 == 0)
{
it = v.erase(it);
}
else {
it++;
}
}
for (int k : v)
{
cout << k << " ";
}
return 0;
}
三、deque容器
deque:双向开口的连续线性空间
-----------------------------------------
头尾两端分别做元素的插入和删除
四、容器适配器
容器适配器是没有迭代器,是不能使用泛型算法的
------------------------------------------------------------
栈:
-------------------------------------------
#include <iostream>
#include <deque>
using namespace std;
template <class T, class Container = deque<T>>
class Stack
{
private:
Container _container;
public:
void push(const T& val)
{
this->_container.push_front(val);
}
void pop()
{
this->_container.pop_front();
}
T& top()
{
return this->_container.front();
}
bool empty()
{
return this->_container.empty();
}
};
int main()
{
Stack<int> s;
s.push(1);
s.push(2);
s.push(3);
while (!s.empty()) {
cout << s.top() << endl;
s.pop();
}
return 0;
}
---------------------------------------------------
优先级队列:
--------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T,class Container = vector<T>, class Compair = std::less<T>>
class Priority_queue
{
private:
Container _container;
Compair _compair;
public:
void push(const T& val)
{
this->_container.push_back(val);
sort(this->_container.begin(),this->_container.end(),this->_compair);
}
void pop()
{
this->_container.pop_back();
}
T& top()
{
return this->_container.back();
}
bool empty()
{
return this->_container.empty();
}
};
int main()
{
Priority_queue<int> pq;
for(int i = 0; i < 20; i++)
{
pq.push(rand() % 100 + 1);
}
while (!pq.empty()) {
cout << pq.top() << " ";
pq.pop();
}
return 0;
}
优先级队列标准库中使用的堆排序:
----------------------------------------------
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
template <class T,class Container = vector<T>, class Compair = std::less<T>>
class Priority_queue
{
private:
Container _container;
Compair _compair;
public:
Priority_queue()
{
make_heap(this->_container.begin(),this->_container.end(),this->_compair);
}
void push(const T& val)
{
this->_container.push_back(val);
push_heap(this->_container.begin(),this->_container.end(),this->_compair);
}
void pop()
{
pop_heap(this->_container.begin(),this->_container.end(),this->_compair);
this->_container.pop_back();
}
T& top()
{
return this->_container.front();
}
bool empty()
{
return this->_container.empty();
}
};
int main()
{
Priority_queue<int> pq;
for(int i = 0; i < 20; i++)
{
pq.push(rand() % 100 + 1);
}
while (!pq.empty()) {
cout << pq.top() << " ";
pq.pop();
}
return 0;
}
五、list容器
链表是一种物理存储单元上非连续、非顺序的存储结构,
数据元素的逻辑顺序是通过链表链接次序实现的
-----------------------------------------------------------
-------------------------------------------------------------
List容器:
------------------
双向循环链表
----------------------
---------------------
在list中插入或删除元素时,
不会引用非它元素的迭代器的失效。
在listAPI有专门的排序算法。
----------------------------------
----------------------------------
list相关API接口:
------------------------
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> ll;
for(int i = 0; i < 20; i++)
{
ll.push_front(rand() % 100 + 1);
}
ll.sort([](int val1, int val2){return val1 > val2;});
for(int k : ll)
{
cout << k << " ";
}
cout << endl;
return 0;
}
-------------------------------------------
六、set容器
-------------------------------------
非线性容器之set/multiset容器(俗称有序容器)树结构,
平衡二叉树
-------------------------
set容器的数据结构:
---------------------------------
Set特性是:所有元素都会根据元素的键值自动被排序。
(set 与 map都会按照键值来自动排序,只不过set的键与值是一体的相同的)
Set的元素不像map那样,可以同时拥有实值与键值,set的元素即是键值又是实值。
(你也可以理解为只有一个值,键与值相同)Set不允许两个元素有相同的键值。
(即然是自动排序,set与map是不允许有相同的键的存在。这一点与map是共同的。)
,而multiset是可以存相同键值的元素。(这是set与multiset的唯一区别。)。
所以set容器的迭代器是一个常双向迭代器,只支持什么:++,--,==,!=的操作。
--------------------------------------------------------------
我们可以通过set的迭代器改变set元素的值吗?
-----------------------------------------------------------
不行,因为set元素值就是其键值,
关系到set元素排序规则,如果任意改变set元素值,
会严重破坏set组织结构。换句话说,set的迭代器是一个只读迭代器。
set容器拥有与list某些相同的性质,
当对容器中的元素进行插入操作或者删除操作的时候,
操作之前所有迭代器,在操作完成之后依
multiset的底层实现是红黑树,红黑树是平衡二叉树的一种。
-----------------------------------------------------------------------
set相关API的介绍及相关策略
-------------------------------------
#include <iostream>
#include <set>
using namespace std;
class Stu
{
private:
string name;
int id;
public:
Stu(string name, int id)
{
this->name = name;
this->id = id;
}
void showInfo()
{
cout << "学号:" << this->id << " ,姓名:" << this->name << endl;
}
bool operator<(const Stu& other)const
{
return this->id < other.id;
}
};
int main()
{
set<int> s;
std::pair<set<int>::iterator,bool> p;
for(int i = 0; i < 20; i++)
{
p = s.insert(rand() % 100 + 1);
if(!p.second)
{
cout << *p.first << "没有插入成功" << endl;
}
}
for(int k : s)
{
cout << k << " ";
}
cout << endl;
cout << "---------------------------------------------" << endl;
Stu stu1("zhangsan",1003);
Stu stu2("lisi",1001);
Stu stu3("wangWu",1002);
set<Stu> s1;
s1.insert(stu1);
s1.insert(stu2);
s1.insert(stu3);
for(Stu stu : s1)
{
stu.showInfo();
}
return 0;
}
-------------------------------
----------------------------
如果,使用自定义类型插入到这个set容器中,
要么在自定义类型中定义<号运算符重载函数,
要么自定义一个函数对象类型,
并重写小括号运算符重载函数。
---------------------------------------
七、对组pair
对组的构造的方式:
-------------------------
-----------------------------
#include <iostream>
#include <map>
using namespace std;
int main()
{
pair<int, string> p1 = {1001,"xialuo"};
pair<int, string> p2(1002,"qiuya");
pair<int, string> p3 = make_pair(1003,"yanhua");
pair<int, string> p4 = map<int,string>::value_type(1004,"dongmei");
map<int,string> m1;
m1.insert(p4);
m1.insert(p2);
m1.insert(p3);
m1.insert(p1);
m1[1005] = "dachun";
m1[1006];
m1[1005] = "zhangjian";
m1.erase(1006);
for(pair<int,string> p : m1)
{
cout << p.first << " ," << p.second << endl;
}
cout << m1.at(1001) << endl;
cout << m1[1001] << endl;
auto it = m1.find(1001);
if(it != m1.end())
{
cout << "id:" << it->first << ",姓名:" << it->second << endl;
}
else {
cout << "没有找到你所斯望的元素" << endl;
}
return 0;
}
八、Map容器
Map容器的特性是:
所有元素都会根据元素的键的值自动排序。
Map所有的元素都是统一的pair对组,
同时拥有键值Key实值Value,
pair的第一元素被视为键值,
第二个元素被视为实值,
map不允许两个元素有相同的键。
--------------------------------------------------------
我们可以通过map迭代器改变map的键值吗?
-------------------------------------------------------------
答案是不行,
因为map的键值关系到map的元素的排列布局,
Map中的键是不可修改的,但是键对应的值是可以修改的。
所以Map的迭代器是一个双向迭代器,只支持++ == !=操作。
Map是可以随时插入或删除键值对的。
Map与multimap的唯一区别是multimap中的键是可以重复的。
Map的底层实现机制是由二叉树中的红黑树进行实现的。
------------------
总结:
------------------
map容器的最小单位是pair对组,
在这个容器中,我们可以通过pair对组的Key通过[ ]中括号运算符或find方法,
找到与之对应的实值,
所以Key与Value之间成映射关系。所以map容器也被称之映射表。