1 string容器
1.1 string基本概念
本质:string是C++风格的字符串,而string本质上是一个类
string和char *的区别:
- char *是一个指针
- string是一个类,类内部封装了char *,管理这个字符串,是一个char *型的容器
特点:
string内部封装了很多成员
例如:查找find,拷贝copy,删除delete替换replace,插入insert
string管理char *所分配的内存,不用担心复制越界和取值越界等,由类内部进行负责
1.2 string构造函数
构造函数原型:
string(); //创建一个空的字符串,例如:string str;
string(const char* s); //使用字符串初始化
string(const string& str); //使用一个string对象初始化另一个string对象
string(int n,char c); //使用n个字符初始化
#include<iostream>
#include<string>
/*
string(); //创建一个空的字符串,例如:string str;
string(const char* s); //使用字符串初始化
string(const string& str); //使用一个string对象初始化另一个string对象
string(int n,char c); //使用n个字符初始化
*/
using namespace std;
void test01()
{
//string是一个类
//我们前期用的一直都是string类的默认构造,也就是下面的方式
//默认构造初始化
string str1;
//使用字符串初始化
const char* str = "hello,world";
string s2(str); //有参构造进行初始化
cout << s2 << endl;
string s3(s2); //拷贝构造进行初始化
cout << s3 << endl;
string s4(5, 'a'); //使用n个字符初始化
cout << s4 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
1.3 string赋值操作
功能描述:给string字符串进行赋值
赋值函数的原型:
string& operator=(const char* s) //char*类型字符串赋值给当前字符串
string& operator=(const string &s) //把字符串s赋值给当前字符串
string& operator=(const 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赋值给字符串
#include<iostream>
#include<string>
/*
string& operator=(const char* s) //char*类型字符串赋值给当前字符串
string& operator=(const string &s) //把字符串s赋值给当前字符串
string& operator=(const 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赋值给字符串
*/
using namespace std;
void test01()
{
string str1;
str1 = "hello world";
cout << str1 <<endl;
string str2;
str2 = str1;
cout << str2 << endl;
string str3;
str3 = 'c';
cout << str3 << endl;
string str4;
str4.assign("hello world");
cout << str4 << endl;
string str5;
str5.assign("hello world",5);
cout << str5 << endl;
string str6;
str6.assign(str5);
cout << str6 << endl;
string str7;
str7.assign(5,'c');
cout << str7 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
1.4 string字符串拼接
功能描述:实现字符串末尾拼接字符串
函数原型:
string& operator+=(const char* str) //重载+=操作符
string& operator+=(const char c) //重载+=操作符
string& operator+=(const string& str) //重载+=操作符
string& append(const char* s) //把字符串s连接到当前字符串结尾
string& append(const char* s,int n) //把字符串s的前n个字符连接到当前字符串结尾
string& append(const string& s) //同operator+=(const string& str)
string& append(const string& s,int pos,int n) //把字符串s从pos开始的n个字符连接到字符串尾部
#include<iostream>
#include<string>
using namespace std;
//字符串拼接
/*
string& operator+=(const char* str) //重载+=操作符
string& operator+=(const char c) //重载+=操作符
string& operator+=(const string& str) //重载+=操作符
string& append(const char* s) //把字符串s连接到当前字符串结尾
string& append(const char* s,int n) //把字符串s的前n个字符连接到当前字符串结尾
string& append(const string& s) //同operator+=(const string& str)
string& append(const string& s,int pos,int n) //把字符串s从pos开始的n个字符连接到字符串尾部
*/
void test01()
{
string str1 = "我";
str1 += "爱玩游戏";
cout << str1 << endl;
str1 += ":";
cout << str1 << endl;
string str2 = "LOL DNF";
str1 += str2;
cout << str1 << endl;
string str3 = "I";
str3.append("Love");
cout << str3 << endl;
str3.append("Game 666",4);
cout << str3 << endl;
str3.append(str2);
cout << str3 << endl;
str3.append(str2, 0, 3); //只截取LOL
cout << str3 << endl;
str3.append(str2, 4, 3); //只截取LOL
cout << str3 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
1.5 string查找和替换
功能描述:【查找:查找指定字符串是否存在】【替换:在指定的位置替换字符串】
函数原型:
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 = 0,int n) const; //从pos位置查找s的前n个字符第一次位置
int find(const char c,int pos = 0) const; //查找字符c第一次出现位置
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 = 0) const; //查找字符c最后一次出现位置
string& replace(int pos,int n ,const string& str) //替换从pos开始n个字符为字符串str
string& replace(int pos,int n,const char* s) //替换从pos开始的n个字符为字符串s
#include<iostream>
#include<string>
using namespace std;
//查找
void test01()
{
string str = "abcdefgde";
int pos = str.find("de");
if (pos == -1)
{
cout << "未查到字符串:" << pos << endl;
}
else
{
cout << "查到字符串:" << pos << endl;
}
//rfind和find的区别,find从左到右查,rfind从右向左查(从右查到的第一个,就是从左到右的最后一个)
pos = str.rfind("de");
if (pos == -1)
{
cout << "未查到字符串:" << pos << endl;
}
else
{
cout << "查到字符串:" << pos << endl;
}
}
//替换
void test02()
{
string str = "abcdefg";
str.replace(1, 3, "1111");
cout << str << endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
总结:
- find查找是从往右,rfind是从右往左
- find找到字符串后返回查找的第一个字符位置,找不到返回-1
- replace在替换时,要指定从那个位置起,多少个字符,替换成什么样的字符串
1.6 string字符串比较
功能描述:字符串之间比较
比较方式:字符串比较是按字符的ASCII码进行对比
= 返回 0
> 返回 1
< 返回 -1
函数原型:
int compare(const string &s) const; //与字符串s比较
int compare(const char *s) const; //与字符串s比较
#include<iostream>
#include<string>
using namespace std;
//查找
void test01()
{
string str1 = "hello";
//string str2 = "hello";
const char* str2 = "hello";
if (str1.compare(str2) == 0)
{
cout << "str1等于ste2" << endl;
}
else if (str1.compare(str2) > 0)
{
cout << "str1大于ste2" << endl;
}
else
{
cout << "str1小于ste2" << endl;
}
}
int main()
{
test01();
system("pause");
return 0;
}
1.7 string字符存取
string中单个字符存取方式有两种
char& operator[](int n) //通过[]方式取字符
char& at(int n) //通过at方式取字符
#include<iostream>
#include<string>
using namespace std;
//查找
void test01()
{
string str1 = "hello";
cout << "str1 = " << str1 << endl;
//1,通过[]获取单个字符
for (int i = 0; i < str1.size(); i++)
{
cout << str1[i] << " ";
}
cout << endl;
//1,通过at获取单个字符
for (int i = 0; i < str1.size(); i++)
{
cout << str1.at(i) << " ";
}
cout << endl;
//修改单个字符
str1[0] = 'x';
cout << "str1 = " << str1 << endl;
str1.at(1) = 'x';
cout << "str1 = " << str1 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
1.8 string插入和删除
功能描述:对string字符串进行插入和删除字符操作
函数原型:
string& insert(int pos,const char* s); //插入字符串
string& insert(int pos,const string& str); //插入字符串
string& insert(int pos,int n,char c); //在指定位置插入n个字符c
string& erase(int pos,int n = npos); //删除从pos开始的n个字符
#include<iostream>
#include<string>
using namespace std;
//查找
void test01()
{
string str1 = "hello";
//字符串插入
str1.insert(1, "111");
cout << str1 << endl;
//字符串删除
str1.erase(1, 3);
cout << str1 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:插入和和删除的起始下标都是从0开始
1.9 string子串
功能描述:从字符串获取想要的子串
函数原型
string& substr(int pos = 0,int n = npos) const; //返回由pos开始的n个字符组成的字符串
#include<iostream>
#include<string>
using namespace std;
void test01()
{
//string子串
string str = "abcdef";
string subStr = str.substr(1, 3);
cout << subStr << endl;
}
//实用操作
void test02()
{
string str = "jackie@qq.com";
//从邮箱名中截取用户名 标志性@前面就是名字
int pos = str.find("@");
string subStr = str.substr(0, pos);
cout << subStr << endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
2 vector容器
2.1 vector基本概念
功能:vector数据结构和数组非常相似,也称为单端数组
vector与普通数组的区别:不同之处在于数组是静态空间,而vector可以动态扩展
动态扩展:并不是在原空间之后续接新空间,而是找更大的内存空间,然后将原数据拷贝到新空间,释放原空间
2.2 vector构造函数
功能描述:创建vector容器并初始化
函数原型:
vector<T> v; //采用模板实现类实现,默认构造函数
vector(v.begin(),v.end()); //将v[begin(),end()]区间的元素拷贝给自身
vector(n, elem) //构造函数将n个elem拷贝给自身
vector(const vector &vec) //拷贝构造函数
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//打印接口
void printVector(vector<int>& v1)
{
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<int> v1; //默认构造
for (int i = 1; i < 10;i++)
{
v1.push_back(i); //插入数据
}
printVector(v1);
vector<int> v2(v1.begin(), v1.end()); //将v1区间的元素拷贝给v2
printVector(v2);
vector<int> v3(10,100); //将10个100拷贝给v3
printVector(v3);
vector<int> v4(v3); //拷贝构造
printVector(v4);
}
int main()
{
test01();
system("pause");
return 0;
}
2.3 vector赋值操作
功能描述:给vector容器进行赋值
函数原型:
vector& operator=(const vector &vec) //重载等号操作符
assign(beg,end); //将[beg,end]区间中的数据拷贝赋值给本身
assign(n,elem); //将n个elem拷贝赋值给本身
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//打印接口
void printVector(vector<int>& v1)
{
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<int> v1;
for (int i = 1; i < 10;i++)
{
v1.push_back(i);
}
printVector(v1);
//赋值操作 operator=
vector<int> v2;
v2 = v1;
printVector(v2);
//区间赋值
vector<int> v3;
v3.assign(v2.begin(),v2.end());
printVector(v3);
//将n个elem赋值给容器
vector<int> v4;
v4.assign(10, 100);
printVector(v4);
}
int main()
{
test01();
system("pause");
return 0;
}
2.4 vector容量和大小
功能描述:对vector容器的容量和大小操作
函数原型:
empty(); //判断函数是否为空
capacity(); //容器的容量
size(); //返回容器中元素的个数
resize(int num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除
resize(int num,elem) //重新指定容器的长度为num,若容器变长,则以elem值填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//打印接口
void printVector(vector<int>& v1)
{
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<int> v1;
for (int i = 1; i < 10;i++)
{
v1.push_back(i);
}
printVector(v1);
if (v1.empty() == true)
{
cout << "v1为空" << endl;
}
else
{
cout << "v1不为空" << endl;
cout << "v1的容量:" << v1.capacity() << endl;
cout << "v1的大小:" << v1.size() << endl;
}
//增加容器的大小
v1.resize(11, 100); //利用重载版本,可以指定默认的填充值,参数2
printVector(v1); //如果比原来长了,那么默认的填充值为0
//减小容器的大小
v1.resize(5); //如果比原来短了,那么会舍弃后面的值,size变小,但是capacity不变
printVector(v1);
}
int main()
{
test01();
system("pause");
return 0;
}
2.5 vector插入与删除
功能描述:对vector容器进行插入,删除操作
函数原型:
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(); //删除容器中所有的元素
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//打印接口
void printVector(vector<int>& v1)
{
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
vector<int> v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
printVector(v1);
//尾删
v1.pop_back();
printVector(v1);
//插入指定位置的元素 第一个参数迭代器
v1.insert(v1.begin()+1,100);
printVector(v1);
//插入多个
v1.insert(v1.begin() + 1,2,1000);
printVector(v1);
//删除指定位置的元素
v1.erase(v1.begin() + 3);
printVector(v1);
//清空
//v1.erase(v1.begin(),v1.end());
v1.clear();
printVector(v1);
}
int main()
{
test01();
system("pause");
return 0;
}
总结:
- 尾插 --- push_back
- 尾删 --- pop_back
- 插入 --- insert (位置迭代器)
- 删除 --- erase (位置迭代器)
- 清空 --- clear
2.6 vector数据存取
功能描述:对vector中的数据存取操作
函数原型:
at(int idx); //返回索引id所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中第一个数据元素
back(); //返回容器中最后一个数据元素
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void test01()
{
vector<int> v1;
//尾插
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
//1,利用迭代器访问容器里面的元素
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//2,利用[]访问容器里面的元素
for (int i = 0; i < v1.size(); i++)
{
cout << v1[i] << " ";
}
cout << endl;
//3,利用at函数访问容器中的元素
for (int j = 0; j < v1.size(); j++)
{
cout << v1.at(j) << " ";
}
cout << endl;
//获取容器中的第一个元素
cout << "第一个元素为:" << v1.front() << endl;
//获取容器中的最后一个元素
cout << "最后一个元素为:" << v1.back() << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
2.7 vector互换容器
功能描述:实现两个容器内元素进行互换
函数原型:
swap(vec); //将vec与本身的元素互换
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//打印接口
void printVector(vector<int>& v1)
{
for (vector<int>::iterator it = v1.begin(); it != v1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//普通操作
void test01()
{
cout << "交换前" << endl;
vector<int> v1;
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
}
printVector(v1);
vector<int> v2;
for (int j = 10; j > 0; j--)
{
v2.push_back(j);
}
printVector(v2);
cout << "交换后" << endl;
v1.swap(v2);
printVector(v1);
printVector(v2);
}
//实际操作 --- 收缩容器
void test02()
{
vector<int> v;
for (int i = 0; i < 10000; i++)
{
v.push_back(i);
}
v.resize(3); //只保留前三个值
cout << "v的容量为:" << v.capacity() << endl; //容量很大
cout << "v的容量为:" << v.size() << endl; //大小为3,这样就说明开辟的空间有点多了
//vector<int>(v)--匿名对象
//这里是拷贝构造利用v初始化一个匿名对象,空间大小为3
vector<int>(v).swap(v);
cout << "v的容量为:" << v.capacity() << endl;
cout << "v的容量为:" << v.size() << endl;
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
2.8 vector预留空间
功能描述:减少vector在动态扩展容量时的扩展次数
函数原理:
reserve(int len) //容量预留len个元素长度,预留位置不初始化,元素不可访问
#include<iostream>
#include<string>
#include<vector>
using namespace std;
void test01()
{
vector<int> v1;
//计算开辟空间次数
int num = 0;
int* p = NULL;
v1.reserve(100000); //提前预留100000空间大小,下面就会值开辟一次空间
for (int i = 0; i < 100000; i++)
{
v1.push_back(i);
if (p != &v1[0])
{
p = &v1[0]; //每次开辟新空间,地址就会发生改变
num++;
}
}
cout << "num= "<<num << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
3 deque容器
3.1 deque容器基本概念
功能:双端数组。可以对头端进行插入删除操作
deque和vector的区别:
- vector对头部的插入删除效率低,数据量越大,效率越低
- deque相对而言,对头部的插入删除速度比vector快
- vector访问元素时的速度会比deque快,这和两者内部实现有关
deque的内部工作原理:
deque内部有个中控器,维护没断缓冲区中的内容,缓冲区存放真实数据,中控器维护的每个缓冲区的地址,使得使用deque时像一片连续的内存空间。deque容器的迭代器支持随机访问的
3.2 deque构造函数
功能描述:deque容器构造
函数原型:
deque<T> deqT; //默认构造形式
deque(beg, end); //构造函数将[beg,end]区间的元素拷贝给自身
deque(n,elem); //构造函数将n个elem拷贝给自身
deque(const deque &deq) //拷贝构造函数
#include<iostream>
#include<string>
#include<deque>
using namespace std;
//当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator
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);
deque<int> d2(d1.begin(), d1.end());
printDeque(d2);
deque<int> d3(10, 100);
printDeque(d3);
deque<int> d4(d3);
printDeque(d4);
}
int main()
{
test01();
system("pause");
return 0;
}
3.3 deque赋值操作
功能描述:给deque容器进行赋值
函数原型:
deque& operator=(const deque &deq); //重载等号操作符
assign(beg, end); //将[beg, end]区间中的数据拷贝赋值给本身
assign(n, elem); //将n个elem拷贝赋值给本身
#include<iostream>
#include<string>
#include<deque>
using namespace std;
//当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator
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;
d2 = d1;
printDeque(d2);
//assign函数赋值
deque<int> d3;
d3.assign(d2.begin(), d2.end());
printDeque(d3);
deque<int> d4;
d4.assign(10, 100);
printDeque(d4);
}
int main()
{
test01();
system("pause");
return 0;
}
3.4 deque大小操作
功能描述:对deque容器的大小进行操作
函数原型:
deque.empty(); //判断容器是否为空
deque.size(); //返回容器中元素的个数
deque.resize(num); //重新指定容器的长度为num,容容器变长,则以默认值哦填充新位置
//如果容器变短,则末尾超出容器长度的元素删除
deque.resize(nnu, elem) //重新指定容器的长度为num,若容器变长,则以elem值填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除
#include<iostream>
#include<string>
#include<deque>
using namespace std;
//当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator
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() == true)
{
cout << "deque容器为空" << endl;
}
else
{
cout << "deque容器不为空" << endl;
cout << "deque容器的大小" << d1.size() << endl;
//deque容器没有容量的概念
}
//重新指定大小
d1.resize(15);
d1.resize(15, 1); //只有比原来大的时候才会填充1
printDeque(d1);
}
int main()
{
test01();
system("pause");
return 0;
}
3.5 deque插入和删除数据
功能描述:向deque容器中插入和删除数据
函数原型:
两端插入操作:
push_back(elem); //在容器末尾插入elem
push_front(elem); //在容器头部插入一个elem
pop_back(); //删除容器的最后一个数据
pop_front(); //删除容器的第一个数据
指定位置操作:
insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置
insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
insert(pos,beg,end); //在pos位置插入[beg,end]区间的数据,无返回值
clear(); //清空容器中的所有数据
erase(beg,end); //删除[beg,end]区间的数据,返回下一个数据的位置
erase(pos); //删除pos位置的数据,返回下一个数据的位置
#include<iostream>
#include<string>
#include<deque>
using namespace std;
//当使用const修饰变量的时候,也就是只读状态,迭代器就需要换成const_iterator
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(1);
//头插
d1.push_front(2);
printDeque(d1);
//尾删
d1.pop_back();
printDeque(d1);
//头删
d1.pop_front();
printDeque(d1);
}
//指定位置操作
void test02()
{
deque<int> d2;
d2.push_back(1);
d2.push_front(2);
//insert插入
d2.insert(d2.begin(),3);
printDeque(d2);
d2.insert(d2.end(), 2, 0);
printDeque(d2);
//指定位置删除
d2.erase(d2.begin());
printDeque(d2);
//区间删除
d2.erase(d2.begin(),d2.begin()+2);
printDeque(d2);
//清空
d2.clear();
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
总结:插入和删除提供的位置都是迭代器!
3.6 deque数据存取
功能描述:对deque中的数据的存取操作
函数原型:
at(int idx); //返回索引idx所指的数据
operator[]; //返回索引idx所指的数据
front(); //返回容器中的第一个数据元素
back(); //返回容器中最后一个数据元素
#include<iostream>
#include<string>
#include<deque>
using namespace std;
void test01()
{
deque<int> d1;
d1.push_back(1);
d1.push_back(2);
d1.push_back(3);
d1.push_front(10);
d1.push_front(20);
d1.push_front(30);
for (int i = 0; i < d1.size(); i++)
{
//通过[]的方式访问所有元素
cout << d1[i] << " ";
}
cout << endl;
for (int i = 0; i < d1.size(); i++)
{
//通过at函数的方式访问所有元素
cout << d1.at(i) << " ";
}
cout << endl;
cout << "返回最后一个数据:" << d1.back() << endl;
cout << "返回第一个数据:" << d1.front() << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:不但可以使用迭代器的方式遍历数据,还可以使用[]和at函数
3.7 deque排序
功能描述:利用算法实现对deque容器进行排序
算法:
sort(iterator beg,iterator end) //对beg和end区间内的元素进行排序
#include<iostream>
#include<string>
#include<deque>
#include <algorithm>
using namespace std;
void printDeque(deque<int> &d)
{
for (int i = 0; i < d.size(); i++)
{
//通过[]的方式访问所有元素
cout << d[i] << " ";
}
cout << endl;
}
void test01()
{
deque<int> d1;
d1.push_back(1);
d1.push_back(2);
d1.push_back(3);
d1.push_front(10);
d1.push_front(20);
d1.push_front(30);
printDeque(d1);
//排序 默认规则从小到大
sort(d1.begin(), d1.end());
printDeque(d1);
}
int main()
{
test01();
system("pause");
return 0;
}
4 案例-评委打分
4.1 案例描述
有5名选手:选手ABCD,10个评委分别对每个选手打分,去除最高分,去除评委中的最低分,取平均分
4.2 实现步骤
- 创建五名选手,放进vector中
- 遍历vector容器,取出每一个选手,执行for循环,可以把10个评分打分存在deque容器中
- sort算法对deque容器中分数排序,去除最高和最低分
- deque容器遍历一遍。累加总分
- 获取平均分
#include<iostream>
#include<string>
#include<deque>
#include<vector>
#include <algorithm>
using namespace std;
class Person
{
public:
Person(string name,int sorce)
{
this->m_Name = name;
this->m_Sorce = sorce;
}
string m_Name;
int m_Sorce;
};
void setSorce(vector<Person> &v)
{
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
deque<int> deq;
//将随机的10个数添加到deque容器中
for (int i = 0; i < 10; i++)
{
int sorce = rand() % 41 + 60;
deq.push_back(sorce);
}
//将这10个数进行展示看一下
cout << (*it).m_Name << " ";
for (deque<int>::iterator de = deq.begin(); de != deq.end(); de++)
{
cout << (*de) << " ";
}
cout << endl;
//排序
sort(deq.begin(),deq.end());
//去掉最大和最小值
deq.pop_back();
deq.pop_front();
int num = 0;
for (deque<int>::iterator de = deq.begin(); de != deq.end(); de++)
{
num += (*de);
}
(*it).m_Sorce = num / deq.size();
}
}
void showSorce(vector<Person>& v)
{
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it).m_Name << " 平均分:" << (*it).m_Sorce << endl;
}
}
int main()
{
vector<Person> v;
//1,创建5名选手,放进vector
for (int i = 0; i < 5; i++)
{
string Num = "ABCDE";
string Name = "选手";
Name += Num[i];
Person p(Name, 0);
v.push_back(p);
}
#if 0
//测试5个选手是否放进vector容器中
for (vector<Person>::iterator it = v.begin(); it != v.end(); it++)
{
cout << "姓名:" << it->m_Name << " 分数: " << it->m_Sorce << endl;
}
#endif
//2,设置分数
setSorce(v);
//3,展示平均分
showSorce(v);
system("pause");
return 0;
}
5 stack容器
5.1 stack基本概念
概念:stack是一种先进后出的数据结构,他只有一个出口
栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为
栈中进入数据称为----入栈push
栈中弹出数据称为----出栈pop
5.2 stack常用接口
功能描述:栈容器常用的对外接口
构造函数:
stack<T> stk; //stack采样模板类实现,stack对象默认构造方式
stack(const stack &stk); //拷贝构造函数
赋值操作:
stack& operator=(const stack &stk) //重载等号操作符
数据存取:
push(elem); //向栈顶添加元素
pop(); //从栈顶移除第一个元素
top(); //返回栈顶元素
大小操作:
empty(); //判断堆栈是否为空
size(); //返回栈的大小
#include<iostream>
#include<string>
#include<stack>
using namespace std;
//stack(栈)的接口
void test01()
{
stack<int> s;
//入栈
s.push(10);
s.push(20);
s.push(30);
//查看栈中的元素 先进后出 且只能查看栈顶元素
while (!s.empty())
{
//查看栈顶
cout << "栈顶元素为:" << s.top() << endl;
//出栈
s.pop();
}
cout << "剩下多少个元素" << s.size() << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
6 queue容器
6.1 queue基本概念
概念:queue是一种先进先出的数据结构,它有两个出口
队列容器允许从一段新增数据,从另一端移除数据
队列中的队头和队尾才可以被外界使用,因此队列不允许有遍历行为
队列中的进数据称为----入队push
队列中的出数据称为----出队pop
#include<iostream>
#include<string>
#include<queue>
using namespace std;
//queue(队列)的接口
void test01()
{
queue<int> q;
//入栈
q.push(10);
q.push(20);
q.push(30);
//查看队列中的元素 先进后出 可以查看队头和队尾
while (!q.empty())
{
//查看
cout << "队头元素为:" << q.front() << endl;
//查看
cout << "队尾元素为:" << q.back() << endl;
//出栈
q.pop();
}
cout << "剩下多少个元素" << q.size() << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
7 list容器
7.1 list基本概念
功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
链表的组成:链表由一系列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域
STL中的链表是一个双向循环链表
由于链表的存储方式并不是连续的内存空间,因此链表list的迭代器只支持前移和后移,属于双向迭代器
list的优点:
- 采用动态存储分配,不会造成内存的浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
list的缺点:
- 链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大
list有一个重要的性质,插入和删除操作都不会造成原有的list迭代器失效,这在vector是不成立的
总结:STL中list和vector是两个最常用到的容器,各有优缺点
7.2 list构造函数
功能描述:创建list容器
函数原型:
list<T> lst; //list采用模板类实现,对象的默认构造形式
list(beg,end); //构造函数将【beg,end】区间中的元素拷贝给本身
list(n,elem); //构造函数将n个elem拷贝给本身
list(const list &lst) //拷贝构造函数
#include<iostream>
#include<string>
#include<list>
using namespace std;
void printList(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
void test01()
{
//默认构造
list<int> L1;
//插入数据
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
printList(L1);
list<int> L2(L1.begin(),L1.end());
printList(L2);
list<int> L3(L2); //拷贝构造
printList(L2);
list<int> L4(2,100); //n个elem
printList(L2);
}
int main()
{
test01();
system("pause");
return 0;
}
7.3 list赋值和交换
功能描述:给list容器进行赋值,以及交换容器
函数原型:
assign(beg,end) //将【beg,end】区间的数据拷贝赋值给本身
assign(n,elem) //将n个elem拷贝赋值给本身
list& operator=(const list &lst) //重载等号运算符
swap(lst) //将lst与本身的元素互换
#include<iostream>
#include<string>
#include<list>
using namespace std;
void printList(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
//赋值
void test01()
{
//默认构造
list<int> L1;
//插入数据
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
printList(L1);
//operator= 赋值
list<int> L2;
L2 = L1;
printList(L2);
//assign赋值操作
list<int> L3;
L3.assign(L2.begin(), L2.end());
printList(L3);
list<int> L4;
L4.assign(10, 100);
printList(L4);
}
//交换
void test02()
{
list<int> L1;
//插入数据
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
list<int> L2;
L2.assign(10, 100);
cout << "交换前" << endl;
printList(L1);
printList(L2);
L1.swap(L2);
cout << "交换后" << endl;
printList(L1);
printList(L2);
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
7.4 list大小操作
功能描述:对list容器的大小进行操作
函数原型:
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
resize(num); //重新指定容器的长度为num,容容器变长,则以默认值填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除
resize(num,elem) //重新指定容器的长度为num,容容器变长,则以elem填充新位置
//如果容器变短,则末尾超出容器长度的元素被删除
#include<iostream>
#include<string>
#include<list>
using namespace std;
void printList(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
//赋值
void test01()
{
//默认构造
list<int> L1;
//插入数据
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
printList(L1);
cout << "L1的大小" << L1.size() << endl;
if (L1.empty())
{
cout << "L1为空" << endl;
}
else
{
cout << "L1为不为空" << endl;
}
L1.resize(5);
printList(L1);
}
int main()
{
test01();
system("pause");
return 0;
}
7.5 list插入和删除
功能描述:对list容器进行数据的插入和删除
函数原型:
push_back(elem); //在容器尾部加入一个元素
pop_back(); //删除容器尾部最后一个元素
push_front(elem); //在容器头部加入一个元素
pop_front(); //删除容器头部第一个元素
insert(pos,elem); //在pos位置插入一个elem,返回新数据的位置
insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值
insert(pso,beg,end); //在pos位置插入【beg,end】区间的数据,无返回值
clear(); //移除容器中的所有数据
erase(beg,end); //删除【beg,end】区间的数据,返回下一个数据的位置
erase(pos); //删除pos位置的数据,返回下一个数据的位置
remove(elem); //删除容器中所有与elem值匹配的元素
#include<iostream>
#include<string>
#include<list>
using namespace std;
void printList(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
//赋值
void test01()
{
list<int> L1;
//尾插
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
//头插
L1.push_front(100);
L1.push_front(200);
L1.push_front(300);
printList(L1);
//尾删和头删
L1.pop_back();
L1.pop_front();
printList(L1);
//insert插入
list<int>::iterator it = L1.begin();
//L1.insert(it + 2, 0); //这里直接加一个int的类型的数据就是直接报错,是因为链表的地址不是连续的,这样是找不到指定位置的
//但是可以L1.insert(++it, 0),可以说明链表的迭代器只能前置加1
L1.insert(++it, 1000);
printList(L1);
//erase删除
L1.erase(++it);
printList(L1);
//remove删除
L1.remove(1000);
printList(L1);
//clear清除
L1.clear();
printList(L1);
}
int main()
{
test01();
system("pause");
return 0;
}
7.6 数据存取
功能描述:对list容器中的数据存取
函数原型:
front(); //返回第一个元素
back(); //返回最后一个元素
#include<iostream>
#include<string>
#include<list>
using namespace std;
void printList(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
//赋值
void test01()
{
list<int> L1;
//尾插
L1.push_back(10);
L1.push_back(20);
L1.push_back(30);
cout << "第一个元素" << L1.front() << endl;
cout << "最后一个元素" << L1.back() << endl;
//cout << L1[0] 错误,不支持[]方式访问
//cout << L1.at(0) 错误,不支持at方式访问
//list容器的迭代器是双向迭代器,不支持随机访问 例如L1.begin()+3
}
int main()
{
test01();
system("pause");
return 0;
}
总结:
- list容器不可以通过[]或者at方式访问数据
- 返回第一个元素---front
- 返回最后一个元素---back
7.7 list反转和排序
功能描述:将容器中的元素反转,以及将容器中的数据进行排序
函数原型:
reverse(); //反转链表
sort(); //链表排序
#include<iostream>
#include<string>
#include<list>
using namespace std;
void printList(list<int> &v)
{
for (list<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
//仿函数
bool mySort(int v1, int v2)
{
return v1 > v2;
}
void test01()
{
list<int> L1;
//尾插
L1.push_back(50);
L1.push_back(20);
L1.push_back(30);
L1.push_back(40);
L1.push_back(10);
cout << "反转前" << endl;
printList(L1);
cout << "反转后" << endl;
L1.reverse();
printList(L1);
cout << "默认排序" << endl;
//所有不支持随机访问迭代器的容器,不可以使用标志算法 例如:sort(L1.begin(),L1.end())
//不支持随机访问的迭代器的容器,内部会提供对应一些算法
L1.sort();
printList(L1);
cout << "从大到小排序" << endl;
L1.sort(mySort);
printList(L1);
}
int main()
{
test01();
system("pause");
return 0;
}
8 set/multiset 容器
8.1 set基本概念
简介:所有元素都会在插入时自动被排序
本质:set/multiset属于关联式容器,底层结构是用二叉树实现。
set和multiset区别:set不允许容器中有重复的元素,mutliset允许容器中有重复的元素
8.2 set构造和赋值
功能描述:创建set容器以及赋值
构造:
set<T> st; //默认构造函数
set(const set &s); //拷贝构造函数
赋值:
set& operator=(const set &s); //重载等号操作符
#include<iostream>
#include<string>
#include<set>
using namespace std;
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> s;
//insert插入数据 set容器只允许insert插入,且插入的数据会自动排序
s.insert(20);
s.insert(10);
s.insert(30);
s.insert(20); //set不允许插入相同的数,其实就是插入相同的数相当于白插,没有用
printSet(s);
//拷贝构造
set<int> s1(s);
printSet(s1);
//operator= 赋值
set<int> s2;
s2 = s1;
printSet(s2);
}
int main()
{
test01();
system("pause");
return 0;
}
总结:set容器插入只能用inset,且插入的数据会自动排序
8.3 set大小和交换
功能描述:统计set容器大小以及交换set容器
函数原型:
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
swap(st); //减缓两个集合容器
#include<iostream>
#include<string>
#include<set>
using namespace std;
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> s;
//insert插入数据 set容器只允许insert插入,且插入的数据会自动排序
s.insert(20);
s.insert(10);
s.insert(30);
s.insert(20); //set不允许插入相同的数,其实就是插入相同的数相当于白插,没有用
printSet(s);
if (s.empty())
{
cout << "容器为空" << endl;
}
else
{
cout << "容器不为空" << endl;
cout << "容器中元素为" << s.size() << endl;
}
//交换
set<int> s2;
s2.insert(20);
s2.insert(10);
s2.swap(s);
printSet(s);
printSet(s2);
}
int main()
{
test01();
system("pause");
return 0;
}
8.4 set插入和删除
功能描述:set容器进行插入数据和删除数据
函数原型:
insert(elem); //在容器中插入元素
clear(); //清除容器中的所有元素
erase(pos); //清除指定位置的元素
erase(beg,end); //清除【beg,end】区间的元素
erase(elem); //清除容器中所有elem元素
#include<iostream>
#include<string>
#include<set>
using namespace std;
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> s;
//insert插入数据 set容器只允许insert插入,且插入的数据会自动排序
s.insert(20);
s.insert(10);
s.insert(30);
s.insert(40);
printSet(s);
//删除
s.erase(s.begin());
printSet(s);
s.erase(30);
printSet(s);
//清空
s.erase(s.begin(), s.end());
s.clear();
printSet(s);
}
int main()
{
test01();
system("pause");
return 0;
}
8.5 set查找和统计
功能描述:对set容器进行查找数据以及统计数据
函数原型:
find(elem); //查找elem是否存在,若存在,返回元素迭代器,不存在,返回set.end()
count(elem); //统计elem的元素个数
#include<iostream>
#include<string>
#include<set>
using namespace std;
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> s;
//insert插入数据 set容器只允许insert插入,且插入的数据会自动排序
s.insert(20);
s.insert(10);
s.insert(30);
s.insert(40);
printSet(s);
//查找,返回的是一个迭代器,所以也需要用一个迭代器来接收
set<int>::iterator pos = s.find(30);
//判断是否找到的方法
if (pos == s.end())
{
cout << "未找到元素" << endl;
}
else
{
cout << "找到元素:" << (*pos) << endl;
}
//统计确定元素的个数,对于set容器而言,要么是1要么是0,因为容器中不允许插入相同值
cout << "30的个数:" << s.count(30) << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:
- 查找 --- find (返回的是迭代器)
- 统计 --- count (对于set,结果为1或者0)
8.6 set和multiset区别
学习目标:掌握set和multise的区别
区别:
- set不可以插入重复值,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以插入重复数据
#include<iostream>
#include<string>
#include<set>
using namespace std;
void test01()
{
//set容器
set<int> s;
//set容器插入数据会返回pair类型,这个类型会告诉你插入的位置(迭代器),还有插入是否成功(bool)
pair<set<int>::iterator, bool> ret = s.insert(10);
if (ret.second)
{
cout << "第一次插入成功" << endl;
}
else
{
cout << "第一次插入失败" << endl;
}
ret = s.insert(10);
if (ret.second)
{
cout << "第二次插入成功" << endl;
}
else
{
cout << "第二次插入失败" << endl;
}
//multiset可以插入重复值,他的返回值是迭代器
multiset<int> ms;
ms.insert(10);
ms.insert(10);
ms.insert(10);
for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:
- 如果不允许插入重复数据可以利用set
- 如果允许插入重复数据可以利用multiset
8.7 pair对组创建
功能描述:成对出现的数据,利用对组可以返回两个数据
两种创建方式:
pair<type,type> p(value1,value2);
pair<type,type> p = make_pair(value1,value2);
#include<iostream>
#include<string>
using namespace std;
void test01()
{
//对组,想要创建两个数据的时候可以使用对组
//第一种创建方式
pair<string, int> p("jackie", 20);
cout << "姓名:" << p.first << " 年龄:" << p.second << endl;
//第一种创建方式
pair<string, int> p1 = make_pair("jackie", 20);
cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:两种方式都可以创建对组,选择一直即可
8.8 set容器排序
学习目标:set容器默认排序规则从小到大,掌握如何改变排序规则
主要技术点:利用仿函数,可以改变排序规则
set存放内置的数据类型
#include<iostream>
#include<string>
#include<set>
using namespace std;
class MyCompare
{
public:
//重载()运算符 仿函数
bool operator()(int value1, int value2)const
{
return value1 > value2;
}
};
void test01()
{
//指定排序规则 从大到小
set<int,MyCompare> s;
s.insert(40);
s.insert(20);
s.insert(30);
s.insert(10);
for (set<int, MyCompare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << (*it) << " ";
}
cout << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:利用仿函数可以指定set容器的排序规则
set存放自定义的数据类型
#include<iostream>
#include<string>
#include<set>
using namespace std;
class Person
{
public:
Person(string name, int age)
{
this->Name = name;
this->Age = age;
}
string Name;
int Age;
};
class MyCompare
{
public:
//重载()运算符 仿函数
bool operator()(Person p1, Person p2)const
{
return p1.Age > p2.Age;
}
};
void test01()
{
//自定义的数据类型,必须指定排序规则,因为默认的排序规则不知道自定义的数据类型如何排序
set<Person,MyCompare> s;
Person p1("张飞", 24);
Person p2("关羽", 22);
Person p3("刘备", 27);
Person p4("赵云", 25);
s.insert(p1);
s.insert(p2);
s.insert(p3);
s.insert(p4);
for (set<Person, MyCompare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << it->Name << " " << it->Age << endl;
}
}
int main()
{
test01();
system("pause");
return 0;
}
总结:对于自定义的数据类型,set容器必须指定排序规则才能插入数据
9 map/multimap容器
9.1 map基本概念
简介:
- map中所有的元素都是pair
- pair中的第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
本质:map/multimap属于关联式容器,底层结构是用二叉树实现
优点:可以根据key值快速找到value值
map/multimap的区别:map不允许容器中有重复的key值元素,multimap允许中有重复的key值
9.2 map构造和赋值
功能描述:对map容器进行构造和赋值操作
函数原理:
构造:
map<T1,T2> mp; //map默认构造函数
map<const map &mp>; //拷贝构造函数
赋值:
map& operator=(const map &mp); //重载等号操作符
#include<iostream>
#include<string>
#include<map>
using namespace std;
void printMap(map<int, int> &m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key=" << (*it).first << " value=" <<it->second <<endl;
}
}
void test01()
{
//默认构造
map<int, int> m1;
//插入数据 必须是pair类型 下面是匿名对象
m1.insert(pair<int,int>(1,10));
pair<int, int> p1(3, 30); //非匿名对象
m1.insert(p1);
m1.insert(pair<int, int>(2, 20));
m1.insert(pair<int, int>(4, 40));
//遍历容器
printMap(m1);
}
int main()
{
test01();
system("pause");
return 0;
}
9.3 map大小和交换
功能描述:统计map容器大小以及交换map容器
函数原型:
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(st); //交换两个容器集合
#include<iostream>
#include<string>
#include<map>
using namespace std;
void printMap(map<int, int> &m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key=" << (*it).first << " value=" <<it->second <<endl;
}
}
void test01()
{
//默认构造
map<int, int> m1;
//插入数据 必须是pair类型 下面是匿名对象
m1.insert(pair<int, int>(1, 10));
m1.insert(pair<int, int>(2, 20));
m1.insert(pair<int, int>(3, 30));
m1.insert(pair<int, int>(4, 40));
if (m1.empty())
{
cout << "容器为空" << endl;
}
else
{
cout << "容器不为空" << endl;
cout << "容器的大小为:" << m1.size() << endl;
}
cout << "交换后" << endl;
map<int, int> m2;
m2.insert(pair<int, int>(5, 500));
m2.insert(pair<int, int>(6, 600));
m2.swap(m1); //交换
printMap(m1);
printMap(m2);
}
int main()
{
test01();
system("pause");
return 0;
}
9.4 map插入和删除
功能描述:map容器进行插入数据和删除数据
函数原型:
insert(elem); //在容器中插入元素
clear(); //清除所有元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(beg,end); //删除区间的所有元素,返回下一个元素的迭代器
erase(key); //删除容器中值为key的元素
#include<iostream>
#include<string>
#include<map>
using namespace std;
void printMap(map<int, int> &m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key=" << (*it).first << " value=" <<it->second <<endl;
}
}
void test01()
{
//插入
map<int, int> m1;
//第一种插入方式
m1.insert(pair<int, int>(1, 10));
//第二种插入方式
m1.insert(make_pair(2, 20));
//第三种插入方式
m1.insert(map<int, int>::value_type(3, 30));
//第四种插入方式 不建议使用第四种方式,其主要作用是用key找到value值 cout << m1[4] << endl;
m1[4] = 40;
printMap(m1);
//erase删除
m1.erase(m1.begin());
printMap(m1);
m1.erase(3);
printMap(m1);
//清空
//m1.erase(m1.begin(), m1.end());
m1.clear();
printMap(m1);
}
int main()
{
test01();
system("pause");
return 0;
}
总结:使用[]的方式插入,如果里面原先有对应的key值,会被覆盖,其他方式则不会,所以不推荐第四种插入方式。
9.5 map查找和统计
功能描述:对map容器进行查找数据以及统计数据
函数原型:
fine(key); //查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回map.end();
count(key); //统计key的元素的个数
#include<iostream>
#include<string>
#include<map>
using namespace std;
void printMap(map<int, int> &m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key=" << (*it).first << " value=" <<it->second <<endl;
}
}
void test01()
{
//插入
map<int, int> m1;
m1.insert(pair<int, int>(1, 10));
m1.insert(pair<int, int>(2, 20));
m1.insert(pair<int, int>(3, 30));
//查找,返回的是位置的迭代器,不存在,返回的m1.end()
map<int, int>::iterator pos = m1.find(3);
if (pos != m1.end())
{
cout << "key = " << (*pos).first << " value = " << (*pos).second << endl;
}
else
{
cout << "元素不存在" << endl;
}
//map统计对应元素的个数除了0就是1,multimap可以大于1
int num = m1.count(3);
cout << "num = " << num << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:查找 --- find 返回的是迭代器
统计 --- count 对于map而言,结果为1或者0
9.6 map容器排序
学习目标:map容器默认排序规则为按照key值进行从小到大的排序,掌握如何改变排序规则
主要技术点:利用仿函数,可以改变排序规则
#include<iostream>
#include<string>
#include<map>
using namespace std;
//仿函数
class MyCompair
{
public:
bool operator()(int v1, int v2)const
{
//降序
return v1 > v2;
}
};
void test01()
{
//默认排序从小到大,修改排序规则
//利用仿函数修改
map<int, int,MyCompair> m1;
m1.insert(make_pair(1, 10));
m1.insert(make_pair(2, 20));
m1.insert(make_pair(3, 30));
for (map<int, int, MyCompair>::iterator it = m1.begin(); it != m1.end(); it++)
{
cout << "key=" << (*it).first << " value=" << it->second << endl;
}
}
int main()
{
test01();
system("pause");
return 0;
}
总结:
- 利用仿函数可以指定map容器的排序规则
- 对于自定义的数据类型,map必须指定排序规则,同set容器