网站建设十胜石,怎么用dw网站怎么建设,那家做网站比较好,线下推广渠道✍个人博客#xff1a;https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 #x1f4da;专栏地址#xff1a;C/C知识点 #x1f4e3;专栏定位#xff1a;整理一下 C 相关的知识点#xff0c;供大家学习参考~ ❤️如果有收获的话#xff0c;欢迎点赞#x1f44d;… ✍个人博客https://blog.csdn.net/Newin2020?spm1011.2415.3001.5343 专栏地址C/C知识点 专栏定位整理一下 C 相关的知识点供大家学习参考~ ❤️如果有收获的话欢迎点赞收藏您的支持就是我创作的最大动力 唠叨唠叨在这个专栏里我会整理一些琐碎的 C 知识点方便大家作为字典查询~ STL
概述
STL学名Standard Template Library一般称它为标准模板库。
C 对模板Template支持得很好STL 就是借助模板把常用的数据结构及其算法都实现了一遍并且做到了数据结构和算法的分离。例如vector 的底层为顺序表数组list 的底层为双向链表deque 的底层为循环队列set 的底层为红黑树hash_set 的底层为哈希表。
从根本上说STL是一些“容器”的集合这些“容器”有list,vector,set,map一大堆STL也是算法和其他一些组件的集合。比如说中sort函数。
STL基本组成
STL从广义上讲分为三类
容器Container是一种数据结构如listvector和deques 以模板类的方法提供。为了访问容器中的数据可以使用由容器类输出的迭代器迭代器Iterator提供了访问容器中对象的方法。例如可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上C的指针也是一种迭代器。但是迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象算法Algorithm是用来操作容器中的数据的模板函数。例如STL用sort()来对一个vector中的数据进行排序用find()来搜索一个list中的对象函数本身与他们操作的数据的结构和类型无关因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用
string容器
用字符数组存放字符串容易发生数组越界的错误而且往往难以察觉。因此C 标准模板库设计了string 数据类型专门用于字符串处理。
要使用string 对象须包含头文件。
在用C 编程时要优先考虑用string 对象来处理字符串因为其用法比字符数组更简单而且不容易出错。
初始化
string对象的初始化和普通类型变量的初始化基本相同只是string作为类还有类的一些特性使用构造函数初始化。
string s1; //默认初始化一个空字符串s1
string s2(s1); //s2是s1的副本
string s3 s1; //等价于s3s1,s3是s1的副本
string s4(“hello”); //s4是字面值”hello”
string s5 “hello”; //等价于上行代码
string s6(n,’a’); //把s6初始化为由连续的n个字符c组成的串
//调用string的构造函数生成一个临时的string类再用临时的string类初始化。
string s7 string(“hello”);
string s8(string(“hello”));输入输出
cin 输入
string s1;
cin s1; //遇到空格终止
cout s1 endl;getline读取整行
string s1;
getline(cin,s1);
cout s1 endl;vs里面使用getline须加上#include 比较大小
string可以直接使用 , 等进行比较。
string s1 “abc”,s2”eda”;
s1 s2
s1 s2
s1 s2链接
string可以使用来直接链接。
string s1 “hello”,s2 “ world”;
string s3 s1 s2;获取字符
使用C11新特性的for
string s1 “abcdefg”;
for (auto c:s1){cout c “ “;
}使用运算符[] size()函数
s1[0];
s1[1];
s1[2];使用迭代器
string s1 “hello world”;
for(auto is1.begin();i!s1.end();i){cout *i “ “;
}拷贝string对象
第一个将s1从下标pos开始拷贝到结尾。当poss1.size()时为未定义行为当poss1.size()拷贝一个空字符。
第二个将s1从下标pos开始拷贝拷贝len个字符。当poss1.size()时为未定义行为当poss2.size()拷贝一个空字符。
string s(s1,pos);
string s(s1,pos,len);案例
string s1(hello);
(1) string s2(s1, 1);//s2为”ello”,长度为4
(2) string s3(s1, 5);//s3为””,长度为0
(3) string s8(s1, 6);// 错误未定义的行为抛出异常
(4) string s4(s1, 1, 3);// s4为”ell”,长度为3
(5) string s5(s1, 1, 8);// 正确s5为”ello”,长度为4
(6) string s6(s1, 5, 8);// s6为””,长度为0
(7) string s7(s1, 6, 1);// 错误未定义的行为抛出异常substr函数
返回一个string对象返回的对象包含s从pos下标开始的n个字符。pos和n均为可选参数。pos默认为下标0n默认为s.size()-pos。
s.substr(pos,n);案例
string s (value);
(1)string s2 s.substr();//s2为”value”,大小为5
(2)string s3 s.substr(2);//s3为”lue”,大小为3
(3)string s4 s.substr(5);//s3为””,大小为0
(4)string s5 s.substr(6);//错误s5的大小为pos 5小于s.size()
(5)string s6 s.substr(1,2);// s6为”al”,大小为2
(6)string s7 s.substr(1,7);// s7为”alue”,大小为4
(7)string s8 s.substr(5,7);// s8为””,大小为0
(8)string s9 s.substr(6,7);// 错误s9的大小为pos 5小于s.size()insert函数
iterator insert( iterator pos, CharT ch )void insert( iterator pos, size_type count, CharT ch )void insert( iterator pos, InputIt first, InputIt last )插入初始化列表
案例
string s1(value);
s1.insert(s1.begin(), s);//执行后s1为svalue
s1.insert(s1.begin(), 1, s);//执行后s1为ssvalue
s1.insert(s1.begin(), s1.begin(), s1.begin());//执行后s1为sssvalue
s1.insert(s1.end(), {1,2});//执行后s1为sssvalue12erase函数
//删除s从pos下标开始的n个字符并返回删除后的s。当pos s.size()时报错
basic_string erase(size_type pos0, size_type nnpos);//删除s迭代器position位置的字符并返回下一个字符的迭代器。
iterator erase(const_iterator position);//删除s迭代器[first,last)区间的字符并返回last字符的迭代器。
iterator erase(const_iterator first, const_iterator last);案例
string s1(value);
string s2(value);
string s3(value);
string s4(value);
s1.erase();//执行后s1为空
s2.erase(0,2); //执行后s2为”lue”
s2.erase(1); //执行后s2为l
s3.erase(s3.begin());//执行后s3为”alue”
s4.erase(s4.begin(),s4.begin());//执行后s4为”alue”append函数
append是在string对象的末尾进行插入操作这一点使用运算符也能做到。
案例
string sC;
s.append(program);//执行完后s”Cprogram”replace函数
案例
string s(i very love China!);const char* cp1 truly;
const char* cp2 truly!!!;string str1 really;
string str2 really!!!;//1.将s从下标2开始删除4个字符删除后在下标2处插入cp1
s.replace(2,4,cp1);//s” i truly love China!”
//2.将s从下标2开始删除5个字符删除后在下标2插入cp2的前5个字符
s.replace(2, 5, cp2,5); //s” i truly love China!”
//3.将s从下标2开始删除5个字符删除后在下标2插入str1
s.replace(2, 5, str1);//s”i really love China!”
//4.将s从下标2开始删除6个字符删除后在下标2插入str2从下标0开始的6个字符
s.replace(2, 6, str2, 0, 6);//s”i really love China!”
//5.将s从下标2开始删除6个字符删除后在下标2插入4个’*’字符
s.replace(2, 6, 4, *);//s”i **** love China!”其他函数
find( )函数
string s 1230,3210,220;
int start 0;
int index s.find(,, start); //从下标为0开始查找返回第一个,的下标如果找不到返回-1ispunct()函数判断字符是否是标点符号用ispunct()
string s;
cin s;
for (auto each : s) {if (!ispunct(each)) {cout each;}
}vector容器
c 中vector 是一个十分有用的容器。它能够像容器一样存放各种类型的对象。也就是说vector是一个能够存放任意类型的动态数组。
vector 是同一种类型的对象的集合每个对象都有一个对应的整数索引值。和string 对象一样标准库将负责管理与存储元素相关的内存。
把vector 称为容器是因为它可以包含其他对象。一个容器中的所有对象都必须是同一种类型的。
头文件
使用vector须包含头文件vector
#include vector声明与初始化
vector 可以声明各种类型整型、字符型、字符串等等
//整形数组
vector int vec { 1,2,3,4,5};
//char型数组
vector char vec1 {h,e,l ,l ,o };
//double
vectordouble vec2 {1.1,2.2,3.3};利用构造函数初始化
vector()创建一个空vector vector(int nSize):创建一个vector,元素个数为nSize
vector(int nSize,const t t)创建一个vector元素个数为nSize,且值均为t
vector(const vector)复制构造函数
vector(begin,end)复制[begin,end)区间内另一个数组的元素到vector中
案例
vector int vec(10);//定义一个含10个变量的整型数组vec默认值都为0
vector int vec(10,2);//定义一个含10个变量的整型数组vec默认值都为2
vectorint vec(a);//其中a也是vector把a整体赋值给vec
vectorint vec(a.begin(),a.begin1);//把a的从开始到第二个赋值给vec遍历函数
reference at(int pos)返回pos位置元素的引用
reference front()返回首元素的引用
reference back()返回尾元素的引用
iterator begin()返回向量头指针指向第一个元素
iterator end()返回向量尾指针指向向量最后一个元素的下一个位置
reverse_iterator rbegin()反向迭代器指向最后一个元素
reverse_iterator rend()反向迭代器指向第一个元素之前的位置
案例
vectorint v { 1,2,3,4,5,6 };
cout v.at(1) endl; // 打印2
cout v.front() endl; //打印1
cout v.back() endl; // 打印6
for (auto i v.begin(); i ! v.end(); i) {cout *i ;
}
//输出1 2 3 4 5 6
cout endl;
for (auto i v.rbegin(); i ! v.rend(); i) {cout *i ;
}
//输出6 5 4 3 2 1添加函数
//向量尾部增加一个元素X
void push_back(const T x);//向量中迭代器指向元素前增加一个元素x
iterator insert(iteratorit,const T x);//向量中迭代器指向元素前增加n个相同的元素x
iterator insert(iterator it,int n,const T x);//向量中迭代器指向元素前插入另一个相同类型向量的[first,last)间的数据
iterator insert(iterator it,const_iterator first,const_iterator last);案例
vectorint v { 1,2 };
vectorint v2 { 100,200 };
v.push_back(3);
v.insert(v.begin(), 11);
v.insert(v.begin() 1, 3, 22);
v.insert(v.begin(), v2.begin(), v2.end());
for (auto i v.begin(); i ! v.end(); i) {cout *i ;
}
//输出100 200 11 22 22 22 1 2 3删除函数
iterator erase(iterator it)删除向量中迭代器指向元素
iterator erase(iterator first,iterator last)删除向量中[first,last)中元素
void pop_back()删除向量中最后一个元素
void clear()清空向量中所有元素
案例
vectorint v { 1,2,3,4,5,6 };
v.erase(v.begin()1);//删除2
v.erase(v.begin() 2, v.begin() 4); //删除4 5
v.pop_back(); //删除最后一个元素
v.clear(); //清空所有元素
for (auto i v.begin(); i ! v.end(); i) {cout *i ;
}判断函数
bool empty() const判断向量是否为空若为空则向量中无元素返回1反之返回0
cout v.empty() endl;大小函数
int size() const返回向量中元素的个数
int capacity() const返回当前向量所能容纳的最大元素值
int max_size() const返回最大可允许的vector 元素数量值
案例
vectorint v { 1,2,3,4,5,6 };
cout v.size() endl; //输出6
cout v.capacity() endl; //输出6
cout v.max_size() endl; //输出4611686018427387903其他函数
void swap(vector)交换两个同类型向量的数据void assign(int n,const T x)设置向量中前n个元素的值为xvoid assign(const_iterator first,const_iterator last)向量中[first,last)中元素设置成当前向量元素
stack容器
stack栈容器是一种先进后出的容器两端只有一个开口只能从这一个开口插入和删除数据。
头文件
使用时包含头文件stack
#includestack构造函数
stackT stkT;//stack采用模板类实现stack对象的默认构造形式
stack(const stack stk);//拷贝构造函数赋值函数
stackoperator(const stack stk);//重载等号操作符数据存取
push(elem);//向栈顶添加元素
pop();//从栈顶移除第一个元素
top();//返回栈顶元素大小函数
empty();//判断堆栈是否为空
size();//返回堆栈的大小queue容器
Queue是一种先进先出First In First Out,FIFO的数据结构它有两个出口。
队列容器允许从一端新增元素从另一端移除元素队列中只有对头和队尾才可以被外界使用因此队列不允许有遍历的行为队列中进数据称为–入队push队列中出数据称为–出队pop 头文件
queue模版类的定义在头文件中。
#includequeue构造函数
queueT queT;//queue采用模板类实现queue对象的默认构造形式
queue(const queue que);//拷贝构造函数
//案例
queueint q1;
queueint q2(q1);相关函数
push(elem);//往队尾添加元素
pop();//从队头移除第一个元素
back();//返回最后一个元素
front();//返回第一个元素
empty();//判断队列是否为空
size();//返回队列的大小deque容器
deque双端队列可以对头端和尾端进行插入删除操作。
deque队列为一个给定类型的元素进行线性处理像向量一样它能够快速地随机访问任一个元素并且能够高效地插入和删除容器的尾部元素。但它又与vector不同deque支持高效插入和删除容器的头部元素。 构造函数
dequeT deqT; //默认构造形式
deque(beg, end); //构造函数将[beg,end]区间中的元素拷贝给本身
deque(n, elem); //构造函数将n个elem拷贝给本身
deque(const deque deq); //拷贝构造函数案例
dequeint a; // 定义一个int类型的双端队列a
dequeint a(10); //定义一个int类型的双端队列a并设置初始大小为10
dequeint a(10, 1); //定义一个int类型的双端队列a并设置初始大小为10且初始值都为1
dequeint b(a); //定义并用双端队列a初始化双端队列b
dequeint b(a.begin(), a.begin()3); //将双端队列a中从第0个到第2个(共3个)作为双端队列b的初始值添加函数
d.push_front(const T x);//头部添加元素
d.push_back(const T x);//末尾添加元素
d.insert(iterator it, const T x);//任意位置插入一个元素
d.insert(iterator it, int n, const T x);//任意位置插入n 个相同元素
d.insert(iterator it, iterator first, iterator last);//插入另一个向量的[forst,last] 间的数据案例
#include iostream
#include deque
using namespace std;
int main(){dequeint d1;//头部增加元素d1.push_front(4);//末尾添加元素d1.push_back(5);//任意位置插入一个元素dequeint::iterator it d1.begin();d1.insert(it, 2);//任意位置插入n个相同元素it d1.begin(); d1.insert(it, 3, 9);//插入另一个向量的[forst,last]间的数据dequeint d2(5, 8);it d1.begin(); d1.insert(it, d2.end() -1, d2.end());//遍历显示for (it d1.begin(); it ! d1.end(); it)cout *it ; // 输出8 9 9 9 2 4 5cout endl;return 0;
}删除函数
d1.pop_front();//头部删除元素
d1.pop_back();//末尾删除元素
d1.erase(iterator it);//任意位置删除一个元素
d1.erase(iterator first, iterator last);//删除[first,last] 之间的元素
d1.clear();//清空所有元素访问函数
下标访问deq[1]; // 并不会检查是否越界
at 方法访问deq.at(1); // 以上两者的区别就是 at 会检查是否越界是则抛出 out of range 异常
访问第一个元素deq.front();
访问最后一个元素deq.back();
大小函数
d.size();//容器大小
d.max_size();//容器最大容量
d.resize();//更改容器大小
deq.empty();//容器判空
deq.shrink_to_fit();//减少容器大小到满足元素所占存储空间的大小其他函数
deq.assign(int nSize, const T x); //多个元素赋值
// 类似于初始化时用数组进行赋值swap(deque);//交换两个同类型容器的元素案例
#include iostream
#include deque
using namespace std;
int main(){// 多个元素赋值dequeint d1;d1.assign(3, 1);dequeint d2;d2.assign(3, 2);// 交换两个容器的元素d1.swap(d2);// 遍历显示cout d1: ;for (int i 0; i d1.size(); i)cout d1[i] ; // 输出2 2 2cout endl;// 遍历显示cout d2: ;for (int i 0; i d2.size(); i)cout d2[i] ; // 输出1 1 1cout endl;return 0;
}list容器
list是一种序列式容器。list容器完成的功能实际上和数据结构中的双向链表是极其相似的list中的数据元素是通过链表指针串连成逻辑意义上的线性表也就是list也具有链表的主要优点即在链表的任一位置进行元素的插入、删除操作都是快速的。 头文件
#includelist初始化
listint l1; //创建一个空链表
listint l2(10); //创建一个链表其有10个空元素
listint l3(5,20); //创建一个链表其有5个元素内容为20
listint l4(l3.begin(),l3.end()); //创建一个链表其内容为l3的内容
listint l5(l4); //创建一个链表其内容为l4的内容迭代器
遍历元素
listint li{1,2,3,4,5,6};
for(listint::iterator itli.begin();it!li.end();it){cout*it ;
}也可以使用auto 常用函数
empty()返回一个bool类型的值只存在真和假当链表为空时为真不为空时为假
size()返回链表元素的个数
链表前插入push_front()表示在链表最前端插入一个数据
删除pop_front()表示在链表最前端删除一个数据
链表后插入push_back()表示在链表尾插入一个数据
删除pop_back()表示将链表尾删除一个数据
插入insert()插入元素到指定位置通过在元素之前在指定位置插入新元素来扩展向量从而有效地增加容器大小所插入的元素数量。
//插入单一数据到指定位置
iterator insert (iterator position, const value_type val);
//插入一段数据到指定位置
void insert (iterator position, size_type n, const value_type val);
//插入一段别的容器的数据到指定位置
template class InputIterator
void insert (iterator position, InputIterator first, InputIterator last);//案例
li.insert(li.begin(),100); //在链表最前端插入数据100
li.insert(li.begin(),3,200); //在链表最前端插入3个数据内容为200
listint k(2,50); //创建一个新的链表k,其拥有2个元素内容均为50
li.insert(li.begin(),li.begin(),li.end()); //在链表v最前端插入链表上K的全部内容erase()删除一个元素或者是一段区间的元素将会自动缩减空间使用。
iterator erase (iterator position);
iterator erase (iterator first, iterator last);//案例
li.erase(li.begin()); //删除
li.erase(li.begin(),li.begin()4); //删除前4个元素排序sort()让整个链表变成升序状态或者变成自定义的排序状态
template class Compare void sort (Compare comp);//案例
#includeiostream
#includelist
using namespace std;
int cmp(const int a,const int b){ return ab;//简单的自定义降序序列
}
int main(){listint li; //创建一个空链表for(int i10;i6;i--){li.push_back(i);}li.push_front(3);li.push_back(20);listint li2(li);for(listint::iterator itli.begin();it!li.end();it){cout*it ;}coutendl;//排序前3 10 9 8 7 6 20//li.sort();for(listint::iterator itli.begin();it!li.end();it){cout*it ;}coutendl;//默认排序后3 6 7 8 9 10 20//li2.sort(cmp);for(listint::iterator itli2.begin();it!li2.end();it){cout*it ;}coutendl;//自定义排序后20 10 9 8 7 6 3//return 0;
}reverse()
相对于自定义的降序方法STL提供了一个默认的降序方法reverse()类似于sort一样直接使用即可。
函数列表
Lst1.assign() 给list赋值
Lst1.back() 返回最后一个元素
Lst1.begin() 返回指向第一个元素的迭代器
Lst1.clear() 删除所有元素
Lst1.empty() 如果list是空的则返回true
Lst1.end() 返回末尾的迭代器
Lst1.erase() 删除一个元素
Lst1.front() 返回第一个元素
Lst1.get_allocator() 返回list的配置器
Lst1.insert() 插入一个元素到list中
Lst1.max_size() 返回list能容纳的最大元素数量
Lst1.merge() 合并两个list
Lst1.pop_back() 删除最后一个元素
Lst1.pop_front() 删除第一个元素
Lst1.push_back() 在list的末尾添加一个元素
Lst1.push_front() 在list的头部添加一个元素
Lst1.rbegin() 返回指向第一个元素的逆向迭代器
Lst1.remove() 从list删除元素
Lst1.remove_if() 按指定条件删除元素
Lst1.rend() 指向list末尾的逆向迭代器
Lst1.resize() 改变list的大小
Lst1.reverse() 把list的元素倒转
Lst1.size() 返回list中的元素个数
Lst1.sort() 给list排序
Lst1.splice() 合并两个list
Lst1.swap() 交换两个list
Lst1.unique() 删除list中重复的元素set/multiset容器
set/multiset属于关联式容器底层结构使用二叉树实现的。
set/multiset的特点是所有的元素在插入时会自动被排序。
而set与multiset容器的区别就是set容器中不允许有重复的元素而multiset允许容器中有重复的元素。
构造和赋值
setT st 默认构造函数
set(const set st) 拷贝构造函数
set operator(const set st) 重载等号操作符插入与删除
insert(elem) 在容器中插入元素
clear() 清除所有元素
erase(pos) 删除pos迭代器所指的元素返回下一个元素的迭代器
erase(beg,end) 删除区间[beg,end)的所有元素返回下一个元素的迭代器
erase(elem) 删除容器中值为elem的元素大小与交换
size() 返回容器中元素的数目
empty() 判断容器是否为空
swap(st) 交换两个集合容器查找与统计
find(key) 查找key是否存在若存在返回该键的元素的迭代器若不存在返回set.end()
count(key) 统计key的元素个数案例
#includeiostream
#include set
using namespace std;
//set容器的查找与统计
int main() {setint s1;//插入数据s1.insert(20);s1.insert(30);s1.insert(10);s1.insert(40);//查找setint::iterator pos s1.find(30);if (pos ! s1.end()) {//找到元素cout 找到该元素: *pos endl;}else {cout 未找到该元素 endl;}//统计//这里需要注意set容器不予许出现重复的元素//因此count返回的值只能为0或者1//统计30的个数s1.insert(30);s1.insert(30);int num s1.count(30);cout 30的个数为: num endl; //1return 0;
}set与multiset容器的区别
Multiset是set集合容器的一种其拥有set的全部内容在此基础之上multiset还具备了可以重复保存元素的功能因此会有略微和set的差别。Multise容器在执行insert()时只要数据不是非法数据和空数据insert就总是能够执行无论时一个数据还是一段数据。Multiset容器中的find()函数回返回和参数匹配的第一个元素的迭代器即时存在多个元素也只是返回第一个如{10,20,20,20}搜索20进行匹配将会返回第二个参数如果没有符合的参数则结束迭代器。同理诸如lower_bound()等的需要进行一个位置的返回值则统统返回第一个发现的值。
map/multimap容器
map容器中所有元素都是pair,pair中第一个元素为key键值起到索引作用第二个元素为value实值。
同时所有元素都会根据元素的键值自动排序。
map/multimap属于关联式容器底层数据结构是用二叉树实现的。它的优点就是可以根据key值快速找到value值。
这里需要了解map与multimap的区别
即map不予许容器中有重复的key值元素而multimap允许容器中有重复的key值元素这里的区别与set与multiset十分类似。
Pair对组
pair只含有两个元素可以看作是只有两个元素的结构体。对于成对出现的数据利用对组可以返回两个数据。
应用
代替二元结构体作为map键值对进行插入在创建pair对象时必须提供两个类型名两个对应的类型名的类型不必相同可以在定义时进行成员初始化。
头文件
#includeutilityvs里面某些编译器可以不声明这个头文件而直接使用貌似在C中pair被放入了std命名空间中了。
格式为
template class T1, class T2 struct pair;在现实情况中我们可以像类似于STL创建新容器一样创建pair也可以直接使用如下
pairint,int p;
pairint,int p(10,20);或者是
mapchar,int m;
m.insert(pairchar,int(a,10));Pair数据访问
//数据类型
pairstring, intp(公孙离, 17);
cout 姓名: p.first 年岁: p.second endl;
//和结构体类似first代表第一个元素second代表第二个元素
pairchar, floatp1make_pair(‘p’,3.14);
cout 字符: p1.first 小数: p1.second endl;make_pair
函数原型template pair make_pair(T1 a, T2 b) { return pair(a, b); }
可以通过make_pair生成我们的所需要的pair对于一般的pair而言如果需要对其进行赋值则需要
pairint,int p;
p.first10,p.second20;但如果使用make_pair方法则可以变成如下内容
pairint,int p;
pmake_pair(10,20);可以看见使用make_pair不仅仅让我们免去了对两个变量进行分开来的访问赋值同时make_pair也智能的接受变量的类型不需要再度指定也就是说make_pair本身是接受隐式类型转换的比如定义的是一个int类型使用make_pair传入一个float类型的参数make_pair不会报错而是回自动的进行一个类型转换将float变为int这样可以获得更高的灵活度同时也会有一些小问题。
构造与赋值
mapT,T mmap 默认构造函数
map(const map mp) 拷贝构造函数
map operator(const map mp) 重载等号操作符案例
#includeiostream
#includemap
using namespace std;
//map容器的构造与赋值
void printMap(mapint, int m) {for (auto it m.begin(); it ! m.end(); it) {cout key it-first value it-second endl;}cout endl;
}
int main() {//创建map容器mapint, int m;//插入数据里面需要传入的是对组m.insert(pairint, int(1, 10));//pairint, int(1, 10)为匿名二元组m.insert(pairint, int(3, 30));m.insert(pairint, int(4, 40));m.insert(pairint, int(2, 20));//插入元素后会根据key自动进行升序排列printMap(m);//拷贝构造mapint, int m2(m);printMap(m2);//赋值mapint, int m3;m3 m2;printMap(m3);return 0;
}大小与交换
size() 返回容器中元素的数目
empty() 判断容器中是否为空
swap(st) 交换两个集合容器插入与删除
insert(elem) 在容器中插入元素
clear() 清除所有元素
erase(pos) 删除pos迭代器所指的元素返回下一个元素的迭代器
erase(beg,end) 删除区间[beg,end)的所有元素返回下一个元素的迭代器
erase(key) 删除容器中值为key的元素案例
#includeiostream
#include map
using namespace std;
int main() {mapint, int m;m.insert(pairint, int(1, 10));//插入第一种m.insert(make_pair(2, 20));//插入第二种m.insert(mapint, int::value_type(3, 30));//插入第三种不建议使用//插入第四种最简单//[]不建议插入通过[]可以利用key访问到value//使用[]插入元素的时候,如果key不存在将会自动创建键值对m[4] 40;printMap(m);m.erase(m.begin());//删除printMap(m);m.erase(3);//删除直接传入keyprintMap(m);//全部删除m.clear();//相当于m.erase(m.begin(),m.end())printMap(m);return 0;
}查找与统计
find(key) 查找key是否存在返回该键的元素的迭代器若不存在返回map.end()
count(key) 统计key的元素的个数案例
#includeiostream
#includemap
using namespace std;
int main() {//查找mapint, int m;m.insert(pairint, int(1, 10));m.insert(pairint, int(3, 30));m.insert(pairint, int(2, 20));//查找键为3的键值对mapint,int::iterator posm.find(3);if (pos ! m.end()) {cout 查到了元素key pos-first value pos-second endl;}else {cout 未找到元素 endl;}//统计//由于map容器中key不能重复出现因此count统计的结果只有0或1int numm.count(3);//返回结果为整型cout num num endl;return 0;
}Multimap容器
Multimap时map映射容器的一种其拥有map的全部内容并在此基础之上multimap还具有了可以重复保存元素的功能与上文的mutliset差不多任何进行访问单个值得语句访问均只会返回第一个位置这里不再多说而是举一个实际中可能用得到得例子。
有没有一种方法使得一个key值能够对应多个value产生一种诸如一个学生有多门考试成绩一样的映射。
我们都知道map关联容器是使得一个数据与另一个数据发生映射的容器通过key得到value产生一一对应那么multimap在此基础上使得map元素可以重复因此这种情况可以使用multimap。