C++的STL容器

STL:标准模板库

STL分为:容器、算法、迭代器
STL六大组件:容器、算法、迭代器、仿函数、适配器(配接器)、空间配置器

1.容器: 各种数据结构,如vector、list、deque、set、map等,用来存放数据
2.算法: 各种常用的算法,如sort、find、copy、for_each等
3.迭代器: 扮演了容器与算法之间的胶合剂。
4.仿函数: 行为类似函数,可作为算法的某种策略
5.适配器:一种用来修饰容器或者仿函数或迭代器接口的东西
6.空间配置器:负责空间的配置与管理

序列式容器:强调值的排序,序列式容器中的每个元素均有固定的位置
关联式容器:二叉树结构,各元素之间没有严格的物理上的顺序关系

迭代器种类

vector容器、存放内置数据类型(理解为数组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <vector>
#include <algorithm>//标准算法头文件
using namespace std;

void Myprint(int val)
{
cout << "line:" << __LINE__ << " value:" << val << endl;
}

//vector容器
void test01(void)
{
//创建了一个vector容器,数组
vector<int> v;

//向容器中插入数据
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);

//通过迭代器访问容器中的数据
vector<int>::iterator itbegin = v.begin(); //起始迭代器,指向容器中第一个元素
vector<int>::iterator itend = v.end(); //结束迭代器,指向容器中最后一个元素的下一个位置

for (; itbegin < itend; itbegin++)
{
cout << "line:" << __LINE__ << " value:" << *itbegin << endl;
}

//第二种迭代器
for (vector<int>::iterator itbegin = v.begin(); itbegin< v.end(); itbegin++)
{
cout << "line:" << __LINE__ << " value:" << *itbegin << endl;
}

//第三种迭代器
for_each(v.begin(), v.end(), Myprint);
}

int main()
{
test01();
}

vector 容器中存放自定义数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

//vector 容器中存放自定义数据类型
class Person
{
public:
Person(string Name, int Age) :m_Name(Name), m_Age(Age)
{ }
~Person()
{}

public:
string m_Name;
int m_Age;
};

void test01(void)
{
vector<Person> v;

Person P1("P1",10);
Person P2("P2", 11);
Person P3("P3", 12);
Person P4("P4", 13);
Person P5("P5", 14);

//向容器中添加数据
v.push_back(P1);
v.push_back(P2);
v.push_back(P3);
v.push_back(P4);
v.push_back(P5);
//遍历容器中数据 it指向一个Person的指针
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
// cout << "name:" << (*it).m_Name << " age:" << (*it).m_Age << endl;
cout << "name:" << it->m_Name << " age:" << it->m_Age << endl;
}
}

//存放自定义数据类型的指针
void test02(void)
{
vector<Person*> v;

Person P1("P1", 10);
Person P2("P2", 11);
Person P3("P3", 12);
Person P4("P4", 13);
Person P5("P5", 14);

//向容器中添加数据
v.push_back(&P1);
v.push_back(&P2);
v.push_back(&P3);
v.push_back(&P4);
v.push_back(&P5);

//遍历容器中数据 iterator it解引用
for (vector<Person*>::iterator it = v.begin(); it != v.end(); it++)
{
Person* p = (*it);
//it -> Person* it_TEMP = &P1;
// cout << "name:" << (*(*it)).m_Name << " age:" << (*(*it)).m_Age << endl;
cout << "name:" << (*it)->m_Name << " age:" << (*it)->m_Age << endl;
}
}

int main(int arv, char ** arg)
{
test01();
test02();
return 0;
}

vector 容器嵌套容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <vector>
using namespace std;

//容器嵌套容器
void test01(void)
{
vector<vector<int>> vv;
//创建小容器
vector<int> v1;
vector<int> v2;
vector<int> v3;
vector<int> v4;
//向小容器中添加数据
for (size_t i = 0; i < 4; i++)
{
v1.push_back((i + 1) * 10);
v2.push_back((i + 1) * 100);
v3.push_back((i + 1) * 1000);
v4.push_back((i + 1) * 10000);
}
//小容器插入到大容器中
vv.push_back(v1);
vv.push_back(v2);
vv.push_back(v3);
vv.push_back(v4);

//通过大容器,把所有数据遍历一遍
for (vector<vector<int>>::iterator it = vv.begin(); it != vv.end(); it++)
{
//(*it)的值是一个 vector<int> 容器
cout << "value:";
for (vector<int>::iterator itt = (*it).begin();itt != (*it).end();itt++)
{
cout << (*itt) << "\t\t";
}
cout << endl;
}
}

int main(int arv, char ** arg)
{
test01();
return 0;
}

string 容器 构造函数

可以理解为字符串使用,本质是一个类,提供了很多的功能函数
构造函数:

1
2
3
4
string();					//创建一个空的字符串 string str;
string(const char * s); //使用字符串s初始化
string(const string &str); //用一个string对象创建另一个string对象
string(int n,char c); //使用n个字符c初始化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>
using namespace std;

//string的构造函数
void test01(void)
{
char str[] = { "hello world" };
string s1;
string s2(str);
cout << "s2:" << s2 << endl;

string s3(s2);
cout << "s3:" << s3 << endl;

string s4(10, 'a');
cout << "s4:" << s4 << endl;
}

int main(int arg,char** arv)
{
test01();
}

string 赋值操作

给string字符串进行赋值

1
2
3
4
5
6
7
string& operator=(const char*s);		//char*类型字符串复制给当前的字符串
string& operator=(const string&s); //把字符串s赋给当前的字符串
string& operator=(char c); //字符赋值给当前的字符串
string& assign(const char *s); //把字符串s赋值给当前的字符串
string& assign(const char *s,int n); //把字符串s的前n个字符赋值给当前的字符串
string& assign(const string &s); //把字符串s赋值给当前的字符串
string& assign(int n,char c); //用n个字符c赋值给当前字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str1;
str1 = "hello world";
cout << "str1=" << str1 << endl;

string str2;
str2 = str1;
cout << "str2=" << str2 << endl;

string str3;
str3 = 'a';
cout << "str3=" << str3 << endl;

string str4;
str4.assign("hello C++");
cout << "str4=" << str4 << endl;

string str5;
str5.assign("hello C++",6);
cout << "str5=" << str5 << endl;

string str6;
str6.assign(str4);
cout << "str6=" << str6 << endl;

string str7;
str7.assign(50, 'c');
cout << "str7=" << str7 << endl;
}

int main(int arv, char ** arg)
{
test01();
return 0;
}

一般 =赋值用的多

string字符串拼接

实现在字符串末尾拼接字符串

1
2
3
4
5
6
7
string &operator +=(const char *str);				//重载+=操作符,str字符串连接到当前字符串结尾
string &operator +=(const char c); //重载+=操作符,c字符连接到当前字符串结尾
string &operator +=(const string &str); //重载+=操作符,str字符串连接到当前字符串结尾
string &append(const char *s); //把字符串s连接到当前字符串结尾
string &append(const char *s,int n); //把字符串s的前n个字符连接到当前字符串结尾
string &append(const string &s); //把字符串s连接到当前字符串结尾,string &operator +=(const string &str)
string &append(const string &s,int pos ,int n); //字符串s中从pos开始的后n个字符连接到字符串结尾
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str1("我");
str1 += "爱美女";
cout << "str1=" << str1 << endl;

str1 += ':';
cout << "str1=" << str1 << endl;

string str2("xxxx");
str1 += str2;
cout << "str1=" << str1 << endl;

string str3("I");
str3.append(" love");
cout << "str3=" << str3 << endl;

str3.append(" beautiful women: abcdef",17);
cout << "str3=" << str3 << endl;

//str3.append(str2);
//cout << "str3=" << str3 << endl;

str3.append(str2,0,2);
cout << "str3=" << str3 << endl;
}

int main(int arv, char ** arg)
{
test01();
return 0;
}

string 查找和替换

查找:查找指定字符串是否存在
替换:在指定的位置替换字符串

1
2
3
4
5
6
7
8
9
10
int find(const string &str ,int pos = 0)const;			//查找str第一次出现位置,从pos开始查找
int find(const char *s ,int pos= 0)const; //查找s第一次出现的位置,从pos开始查找
int find(const char *s,int pos,int n)const; //从pos位置查找s的前n个字符第一次位置
int find(const char c,int pos = 0)const; //查找字符c第一次出现的位置,从pos开始查找
int rfind(const string&str,int pos=npos)const; //查找str最后一次位置,从pos开始查找
int rfind(const char *s ,int pos=npos)const; //查找s最后一次出现的位置,从pos开始查找
int rfind(const char *s,int pos,int n)const; //从pos位置查找s的前n个字符最后一次位置
int rfind(const char c,int pos =npos)const; //查找字符c最后一次出现的位置,从pos开始查找
string &replace(int pos ,int n,const string&str); //替换从pos开始n个字符为字符串str
string &replace(int pos ,int n,const char *s); //替换从pos开始n个字符为字符串s

字符在查找时候,我们是有一个起始的下标,指定开始从那开始查起
find与rfind区别
查到字符串:返回查找到字符串的首地址,否则返回-1
find查找是从左往右查找,如果指定位置,则从指定位置处往后查找; rfind是从右往左查找,如果指定位置,则从指定位置处往前查找

替换

如果替换字符长度在最后,会把需要替换的字符,合并到一起
replace在替换时,要指定从那个位置起(pos),多少个字符(n),替换成什么样的字符串(str || s)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str1 = "abcdefghidede";
int pos = str1.find("de",0);//查到字符串:返回查找到字符串的首地址,否则返回-1
if (pos == -1)
{
cout << "未找到字符串" << endl;
}
else
{
cout << "找到字符串,pos = " << pos << endl;
}
//find与rfind区别
//find查找是从左往右查找,rfind是从右往左查找
pos = str1.rfind("de",9);
if (pos == -1)
{
cout << "未找到字符串" << endl;
}
else
{
cout << "找到字符串,pos = " << pos << endl;
}
}

void test02(void)
{
string str1 = "abcdefg";
//从1号位置起3个字符替换为“1111”
str1.replace(1,3,"1111");
cout << "str1 char * = " << str1 << endl; //str1 char * = a1111efg

string str2 = "123456";
str1.replace(str1.rfind('g',str1.size()),str2.size(),str2);
//用str2替换g位置的数据,
cout << "str1 string = " << str1 << endl; //str1 string = a1111ef123456
}

int main(int arg, char**arv)
{
test01();
test02();
return 0;
}

string 字符串的比较

字符串之间的比较,两个字符串相等 返回0 ,第一个字符串大于第二个字符串 返回1 ,第二个字符串大于第一个字符串 返回-1

1
2
int compare(const string &s) const;			//与字符串s比较
int compare(const char *s) const; //与字符串s比较
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str1 = "xello";
string str2 = "hello";

int compare = str1.compare(str2);

switch (compare)
{
case 0:
cout << "str1 == str2" << endl;
break;

case 1:
cout << "str1 > str2" << endl;
break;

case -1:
cout << "str1 < str2" << endl;
break;

default:
break;
}
}

int main(int arg, char **arv)
{
test01();
return 0;
}

string 字符存取

string 中单个字符存存取方式有两种

1
2
char & operator[](int n);					//通过[]方式取字符
char &at(int n); //通过at方法获取字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str = "hello";
//
//通过[] 访问单个字符
for (int i = 0; i < str.size(); i++)
{
cout << str[i] << " ";
}
cout << endl;

for (int i = 0; i < str.size(); i++)
{
cout << str.at(i) << " ";
}
cout << endl;

//修改单个字符
str[0] = 'x';
cout << str << endl; //xello
str.at(1) = 'x';
cout << str << endl; //xxllo
}

int main(int arg, char **arv)
{
test01();
return 0;
}

string 插入和删除

string 字符串进行插入和删除字符操作

1
2
3
4
string &insert(int pos const char *s);		//插入字符串
string &insert(int pos ,string &str); //插入字符串
string &insert(int pos ,int n,char c); //在指定位置插入n个字符c
string %erase(int pos ,int n = npos); //删除从pos开始的n个字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str = "hello";
//插入
str.insert(1, "111");
cout << "str = " << str << endl; //str = h111ello
//删除
str.erase(1, 3);
cout << "str = " << str << endl; //str = hello
}

int main(int arg, char **arv)
{
test01();
return 0;
}

string子串

从字符串中获取想要的子串,使用子串可以获取到有用信息

1
string &substr(int pos = 0, int n = npos) const;			//返回由pos开始的n个字符组成的字符串
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>
using namespace std;

void test01(void)
{
string str = "hello";
string substr = str.substr(1, 3);
cout << "substr = " << substr << endl;
}

//实用操作
void test02(void)
{
string email = "zhangsan@sina.com";
//从邮件地址中获取用户名信息
int pos = email.find('@', 0);
//获取用户名称
string userName = email.substr(0, pos);
cout << "userName = " << userName << endl;
}

int main(int arv, char **arg)
{
test01();
test02();
return 0;
}

vector 容器 最常见的容器之一

vector 数据结构和数组非常相似,也称为单端数组

vector 与普通数组区别:
不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展:并不是在原空间之后续接新空间,而是找到更大的内存空间,然后将原数据拷贝新空间,释放原空间

vector 容器不会在前端插入数据,都是在尾部插入或删除数据 pusb_back pop_back
front() //第一个元素
back() //最后一个元素
常用的迭代器 begin() end()(指向最后一个元素的下一个位置)
rbegin:指向倒数第一个元素,rend()指向第一个元素的前一个位置

vector 容器的迭代器是支持随机访问

vector 构造函数

1
2
3
4
vector<T> V;				//采用模板实现类实现,默认构造函数
vector(v.begin(),v.end()); //将v的begin()起始地址,到end()前一个地址数据拷贝给本身
vector(n,elem); //构造函数将n个elem拷贝给本身,构造函数
vector(const vector &vec); //拷贝构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

template<typename T>
void test02(T begin,T end)
{
for (T it = begin; it < end; it++)
{
cout << *it << " ";
}
cout << endl;
}

void printVector(vector<int>& v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}

void test01()
{
vector<int> v1;

for (size_t i = 0; i < 10; i++)
{
v1.push_back(i);
}

printVector(v1);

vector<int > v2(v1.begin(), v1.end() - 3);
printVector(v2);
test02(v2.begin(),v2.end());

vector<int> v3(10, 100);
test02(v3.begin(), v3.end());

vector<int> v4(v3);
test02(v4.begin(), v4.end());
}

int main()
{
test01();
return 0;
}

#vector 赋值操作
给vector容器进行赋值

1
2
3
vector &operator=(const vector &vec);	//重载等号操作符(最简单的赋值方式)
assign(beg,end); //将[beg,end)区间中的数据拷贝赋值给本身
assign(n,elem); //将n个elem拷贝赋值给本身
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

void printVector(vector<int> & v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}

void test01(void)
{
vector<int> v1;
for (size_t i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);

vector<int> v2 = v1;
printVector(v2);

vector<int> v3;
v3.assign(v1.begin(), v1.end() - 3);
printVector(v3);

vector<int> v4;
v4.assign(10, 10);
printVector(v4);
}

int main()
{
test01();
return 0;
}

vector 容量和大小

对vector容器的容量和大小操作

1
2
3
4
5
6
7
empty();						//判断容器是否为空 返回true表示容器为空,fasle表示容器不为空
capacity(); //容器的容量
size(); //返回容器中元素的个数 (capacity >= size)
resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。
//如果容器变短,则末尾超出容器长度的元素被删除。
resize(int num,elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除。

容器容量一定大于或等于元素个数,元素个数可能是不是满的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <vector>
using namespace std;

void printVector(vector<int> & v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}

void test01()
{
vector<int> v1;
for (size_t i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);

if (v1.empty()) //为真 代表容器为空
{
cout << "v1 容器为空" << endl;
}
else
{
cout << "v1 容器不为空" << endl;
cout << "v1的容量为: " << v1.capacity() << endl;
cout << "v1元素个数: " << v1.size() << endl;
}
//重新指定大小
v1.resize(15);
printVector(v1); //0 1 2 3 4 5 6 7 8 9 0 0 0 0 0
//如果重新指定比的比原来长了,新增加的位置使用默认值0填充新的位置
cout << "v1的容量为: " << v1.capacity() << endl;
cout << "v1元素个数: " << v1.size() << endl;

v1.resize(20,100); //指定默认填充值
printVector(v1); //0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 100 100 100 100 100
//如果重新指定比的比原来长了,新增加的位置使用指定的值填充新的位置
cout << "v1的容量为: " << v1.capacity() << endl;
cout << "v1元素个数: " << v1.size() << endl;

v1.resize(5); //如果重新指定的长度比原来短了,超出部分会删除掉
printVector(v1); //0 1 2 3 4
cout << "v1的容量为: " << v1.capacity() << endl;
cout << "v1元素个数: " << v1.size() << endl;
}

int main()
{
test01();
return 0;
}

vector 插入和删除

1
2
3
4
5
6
7
push_back(ele);										//尾部插入元素ele
pop_back(); //删除最后一个元素
insert(const_iterator pos,ele); //迭代器指向位置pos插入元素ele
insert(const_iterator pos,int count,ele); //迭代器指向位置pos插入count个元素ele
erase(const_iterator pos); //删除迭代器指向的元素
erase(const_iterator start,const_iterator end); //删除迭代器从start到end之间的元素,删除包含其实地址,不包含结束地址区域数据
clear(); //删除容器中的所有元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <vector>
using namespace std;

void printVector(vector<int> &v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}

void test01(void)
{
vector<int> v1;

v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);

printVector(v1);

v1.pop_back();
printVector(v1);

v1.insert(v1.begin() + 2, 100);
printVector(v1);

v1.insert(v1.begin() + 2, 3,0xFF);
printVector(v1);

v1.erase(v1.begin() + 2);
printVector(v1);

v1.erase(v1.begin() + 2, v1.begin() + 5);
printVector(v1);

cout << "clear" << endl;
v1.clear();
printVector(v1);
}

int main()
{
test01();
return 0;
}

vector 数据存取

1
2
3
4
at(int idx);					//返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <vector>
using namespace std;

void test01()
{
vector<int> v1;
for (size_t i = 0; i < 10; i++)
{
v1.push_back(i);
}

for (size_t i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;

for (size_t i = 0; i < v1.size(); i++)
{
cout << v1.at(i) << " ";
}
cout << endl;

cout << "返回第一个元素:" << v1.front() << endl;
cout << "返回最后一个元素:" << v1.back() << endl;
}

int main()
{
test01();
return 0;
}

vector互换容器

实现两个容器内元素进行互换
巧用swap可以收缩内存空间

1
swap(vec);					//将vec与本身的元素互换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <vector>
using namespace std;

void printVector(vector<int> &v)
{
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << "\t";
}
cout << endl;
}

void test01()
{
vector<int> v1;
vector<int> v2;
for (size_t i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(9-i);
}
cout << "v1 与 v2数据交换前" << endl;
printVector(v1);
printVector(v2);

cout << "v1 与 v2数据交换后" << endl;
v1.swap(v2);
printVector(v1);
printVector(v2);
}

//实际用途
//巧用swap可以收缩内存空间
void test02()
{
vector<int> v;
for (size_t i = 0; i < 100000; i++)
{
v.push_back(i);
}

cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小:" << v.size() << endl;

v.resize(3);//重新指定大小,容量不变 现在是容量很大,但是没有使用
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小:" << v.size() << endl;

//巧用swap收缩内存
vector<int>(v).swap(v);
//vector<int>(v)
//这里是一部分,这里叫做匿名对象,相当用v构造了一个新的对象 \
(相当于调用了拷贝构造函数,将v中的数据拷贝到匿名对象中),新对象名字是匿名的,没有名字; \
按照v来给匿名对象进行初始化操作,会按照v所用的元素个数来初始化匿名对象元素个数
//.swap(v)
//相当于匿名对象调用了交换函数,然后他们的数据空间,互相指向对方,这样子就交换完成了。内存也收缩了,\
匿名对象空间指会在函数结束后,进行释放空间,这里系统进行了操作
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的大小:" << v.size() << endl;
}

int main()
{
test01();
test02();
return 0;
}

swap可以使两个容器互换,可以达到实用的收缩内存效果

vector 预留空间

减少vector在动态扩展容量时的扩展次数,就是一开始就分配这么大的一个空间出来,

1
reserve(int len);			//容器预留len个元素长度,预留位置不初始化,元素不可访问

预留你指定的长度,但是预留空间是没有数据的,只是分配内存,未初始化内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <vector>
using namespace std;

void test01()
{
vector<int> v;

int num = 0;//统计开辟次数
int *p = NULL;

for (size_t i = 0; i < 100000; i++)
{
v.push_back(i);
if (p != &v[0])
{
p = &v[0];
num++;
cout << "v.capacity = " << v.capacity() << endl;
}
}
cout << "v动态扩展次数:" << num << endl;//分配30次,每次扩展1.5倍

vector<int> v1;
v1.reserve(30000);
num = 0;
for (size_t i = 0; i < 100000; i++)
{
v1.push_back(i);
if (p != &v1[0])
{
p = &v1[0];
num++;
cout << "v1.capacity = " << v1.capacity() << endl;
}
}
cout << "v1动态扩展次数:" << num << endl;
}

int main()
{
test01();
return 0;
}

如果数据量较大,可以一开始利用reserve预留空间