c++学习笔记-提高篇-STL标准模板库4(set容器、map容器)
set容器
一、set的基本概念
1.简介:所有元素都会在插入时自动被排序
2.本质:set/multiset属于关联式容器,底层结构是用二叉树实现
3.set和multiset区别
set不允许容器中有重复元素
multiset允许容器中有重复元素
二、set构造和赋值
1.描述:创建set容器以及赋值
2.构造:
- set<T>st;? ? ? ? ? ? ? ? // 默认构造函数
- set(const set &st)? ?//拷贝构造函数
3.赋值:
- set& operator=(const set &st)? ?//重载等号操作符
4.示例
set容器插入数据时用insert
set容器插入数据会自动排序
#include<iostream>
using namespace std;
#include<set>
//set容器构造和赋值
void printSet(set<int>s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
set<int>s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(30);
s1.insert(30);
s1.insert(30);
//遍历容器
//set容器的特点,所有元素被插入的时候会自动排序
//set容器不允许插入重复的值
printSet(s1);
//拷贝构造
set<int> s2(s1);
printSet(s2);
//赋值操作
set<int> s3;
s3 = s2;
printSet(s3);
}
int main()
{
test01();
system("pause");
return 0;
}
三、set大小和交换
1.描述:set容器的大小、是否为空、交换
2.构造:
- size();? ? ? ? ? ? ? ? ? ? ?//返回容器中元素的个数
- empty();? ? ? ? ? ? ? ? ?//判断容器是否为空
- swap(st);? ? ? ? ? ? ? ?//交换两个集合容器
3.示例:
#include<iostream>
#include<set>
using namespace std;
//set容器 大小和交换
void printSet(set<int> &s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//大小
void test01()
{
set<int> s1;
//插入数据
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
printSet(s1);
//判断是否为空
if (s1.empty())
{
cout << "s1为空" << endl;
}
else
{
cout << "s1不为空" << endl;
cout << "s1的元素大小:" << s1.size()<< endl;
}
}
//交换
void test02()
{
set<int> s1;
s1.insert(10);
s1.insert(30);
s1.insert(20);
s1.insert(40);
set<int> s2;
s2.insert(200);
s2.insert(100);
s2.insert(400);
s2.insert(300);
cout << "交换前:" << endl;
printSet(s1);
printSet(s2);
cout << "交换后:" << endl;
s1.swap(s2);
printSet(s1);
printSet(s2);
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
四、set插入和删除
1.描述:set容器进行插入数据和删除数据
2.构造:
- insert(elem);? ? ? ? ? ? ? ? ? ? ?//在容器中插入元素
- clear();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //清除所有元素
- erase(pos);? ? ? ? ? ? ? ? ? ? ? ?//删除pos迭代器所指向的元素,返回下一个元素的迭代器
- erase(beg,end);? ? ? ? ? ? ? ? //删除区间[beg,end]的所有元素,返回下一个元素的迭代器
- erase(elem);? ? ? ? ? ? ? ? ? ? ?// 删除容器中值为elem的元素
3.示例:
#include<iostream>
using namespace std;
#include<set>
#include<vector>
//set容器的插入和删除
void printSet(set<int> &s)
{
for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
set<int>s1;
//插入
s1.insert(20);
s1.insert(10);
s1.insert(40);
s1.insert(30);
//遍历
printSet(s1);
//删除
s1.erase(s1.begin());
printSet(s1);
//删除重载版本
s1.erase(30);
printSet(s1);
//清空
//s1.erase(s1.begin(),s1.end());
s1.clear();
printSet(s1);
}
int main()
{
test01();
system("pause");
return 0;
}
五、set容器查找和统计
1.描述:对set容器进行查找数据以及统计数据
2.构造:
- find(key);? ? //查找key是否存在,若存在,返回该元素的迭代器;若不存在,返回set.end()
- count(key);?//统计key的元素个数
3.示例:
#include<set>
#include<iostream>
using namespace std;
//set容器查找和统计
void test01()
{
//查找
set<int>s1;
//插入数据
s1.insert(30);
s1.insert(20);
s1.insert(10);
s1.insert(40);
set<int>::iterator pos = s1.find(40);
if (pos != s1.end()) //s1.end()指向最后一个元素的下一个位置
{
cout << "找到元素:" << *pos << endl;
}
else
{
cout << "未找到元素" << endl;
}
//对于set而言,统计结果不是0就是1
//对于multiset而言,统计结果大于1
}
//统计
void test02()
{
set<int> s1;
s1.insert(10);
s1.insert(20);
s1.insert(30);
s1.insert(10);
int num = s1.count(100);
cout << "统计nus = " << num << endl;
}
int main()
{
test02();
system("pause");
return 0;
}
注意:? ?count 对于set而言,统计结果不是0就是1;对于multiset而言,统计结果大于1
六、set和multiset的区别
1.区别:
- set不可以插入重复数据,而multiset可以
- set插入数据的同时会返回插入结果,表示插入是否成功
- multiset不会检测数据,因此可以重复插入
2.示例:
#include<iostream>
#include<set>
using namespace std;
//set容器和multiset容器的区别
void test01()
{
set <int>s;
pair<set<int>::iterator, bool> ret = s.insert(10);
if (ret.second)
{
cout << "第一次插入成功" << endl;
}
else
{
cout << "第一次插入失败" << endl;
}
pair<set<int>::iterator,bool> ret2 = s.insert(10);
if (ret2.second)
{
cout << "第二次插入成功" << endl;
}
else
{
cout << "第二次插入失败" << endl;
}
multiset<int>s1;
//允许插入重复值
s1.insert(20);
s1.insert(20);
for (multiset<int>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << endl;
}
cout << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
七、pair对组创建
1.功能描述:成对出现的数据,利用对组可以返回两个数组
2.两种创建方式:
- pair<type,type> p(value1,value2)
- pair<type,type> p = make_pair(value1,value2)
3.示例
#include<string>
#include<iostream>
using namespace std;
//pair对组的创建
void test01()
{
//第一种方式
pair<string, int> p("Tom", 20);
cout << "姓名:" << p.first << " 年龄:" << p.second << endl;
pair<string, int> p2 = make_pair("Jerry", 30);
cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
?八、set容器排序
1.学习目标:
- set容器默认排序规则为从小到大,掌握如何改进排序规则
2.主要技术点:
- 利用仿函数,可以改变排序规则?
3.示例一:set存放内置数据类型
#include<iostream>
#include<set>
using namespace std;
//set容器排序
class MyCompare
{
public:
bool operator()(int v1, int v2) const
{
return v1 > v2;
}
};
void test01()
{
set<int>s1;
s1.insert(10);
s1.insert(40);
s1.insert(20);
s1.insert(50);
s1.insert(30);
for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
//指定排序规则为从大到小
set<int, MyCompare>s2;
s2.insert(10);
s2.insert(40);
s2.insert(20);
s2.insert(50);
s2.insert(30);
for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
注意仿函数中,operator()重载“()”时需要加const
class MyCompare
{
public:
?? ?bool operator()(int v1, int v2) const
?? ?{
?? ??? ?return v1 > v2;
?? ?}
};
没加const报错的原因:通过在 operator()
函数后加上 const
修饰符,你告诉编译器这个函数不会修改对象的状态,因此可以在 const
对象上调用。这样应该能够解决与 C3848
错误相关的问题。
总结:利用仿函数指定set容器的排序规则
4.示例二:set存放自定义数据类型
#include<iostream>
#include<set>
#include<string>
using namespace std;
//set容器排序,存放自定义数据类型
class Person
{
public:
Person(string name,int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
class comparePerson
{
public:
bool operator()(const Person & p1, const Person & p2) const
{
//按照年龄降序
return p1.m_Age > p2.m_Age;
}
};
void test01()
{
//自定义的数据类型 都会指定排序规则
set<Person,comparePerson> s1;
//创建Person对象
Person p1("刘备", 24);
Person p2("张飞", 14);
Person p3("关羽", 50);
Person p4("Jerry", 28);
Person p5("Tom", 39);
s1.insert(p1);
s1.insert(p2);
s1.insert(p3);
s1.insert(p4);
s1.insert(p5);
for (set<Person, comparePerson>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
}
}
int main()
{
test01();
system("pause");
return 0;
}
map容器
一、map的基本概念
1.简介:
- map中所有元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值自动排序
2.本质:
- map/multimap属于关联式容器,底层结构是二叉树
3.优点:
- 可以根据key值快速查找到value值
4.map/multimap区别
- map不允许容器中有重复key值元素
- multimap允许容器有重复key值元素
二、map构造和赋值
1.功能描述:对map容器进行构造和赋值操作
2.函数原型:
构造:
- map<T1,T2> mp;? ? //map默认构造
- map(const map &mp);? ? //拷贝构造函数
赋值:
- mp& operator = (const map &mp)? ?//重载等号运算符
3.示例:
#include<iostream>
#include<map>
using namespace std;
//map容器 构造和赋值
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;
}
cout << endl;
}
void test01()
{
//创建map容器
map<int, int> m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 30));
m.insert(pair<int, int>(3, 30));
printMap(m);
//拷贝构造
map<int, int>m2(m);
printMap(m2);
//赋值
map<int, int>m3;
m3 = m2;
printMap(m3);
}
int main()
{
test01();
system("pause");
return 0;
}
总结:map中所以元素是成对出现,插入数据时要使用对组
二、map容器大小和交换
1.功能描述:统计map容器大小以及交换map容器
2.函数原型
- size();? ? ? ? //返回容器中元素的数目
- empty();? ? //判断容器是否为空
- swap();? ? ?//交换两个集合
3.示例:
#include<iostream>
#include<map>
using namespace std;
//map容器 大小和交换
void printMap(map<int, int>& m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "k = " << it->first << " value" << it->second << endl;
}
cout << endl;
}
void test01()
{
//大小
map<int, int> m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(4, 30));
m.insert(pair<int, int>(3, 20));
if (m.empty())
{
cout << "m为空" << endl;
}
else
{
cout << "m不为空" << endl;
cout << "m大小:" << m.size() << endl;
cout << "m内容:" << endl;
printMap(m);
}
}
void test02()
{
map<int, int> m;
//for (int i = 1; i < 4; i++)
//{
// m.insert(pair<int, int>(i, i*10));
//}
//printMap(m);
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(2, 20));
map<int, int>m2;
m2.insert(pair<int, int>(4, 40));
m2.insert(pair<int, int>(6, 60));
m2.insert(pair<int, int>(3, 80));
cout << "交换前:" << endl;
cout << "m:" << endl;
printMap(m);
cout << "m2:" << endl;
printMap(m2);
cout << "-------------------------------" << endl;
swap(m, m2);
cout << "交换后:" << endl;
cout << "m:" << endl;
printMap(m);
cout << "m2:" << endl;
printMap(m2);
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
三、map容器插入和删除
1.功能描述:map容器进行插入数据和删除数据‘
2.函数原型:
- insert(elem);? ? //在容器中插入元素
- clear();? ? ? ? ? ? ?// 清除所以元素
- erase(pos);? ? ? //删除pos迭代器所指的元素,返回下一个元素的迭代器
- erase(beg,end);? ? ? //删除(beg,end)区间的元素,返回下一个元素的迭代器
- erase(key);? ? ? ? ? ? //删除key值和其元素
3.示例:
#include<iostream>
#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;
}
cout << endl;
}
void test01()
{
map<int, int>m;
//插入
//第一种
m.insert(pair<int, int>(1, 10));
//第二种
m.insert(make_pair(2, 20));
//第三种
m.insert(map<int, int>::value_type(0, 10));
//第四种
m[4] = 40;
//cout << m[5] << endl;//没有的时候默认插入0
printMap(m);
//删除
m.erase(m.begin());
printMap(m);
m.erase(2);//按照key删除
printMap(m);
m.erase(m.begin(),m.end());//清空
printMap(m);
m.insert(pair<int,int>(0, 33));
m.clear();//也是清空
printMap(m);
}
int main()
{
test01();
system("pause");
return 0;
}
四、map容器查找和统计
1.对map容器进行查找数据以及统计数据
2.函数原型
- find(key);? ? //查找key是否存在,返回该键的元素的迭代器;若不存在,返回set.end()
- count(key);? //统计key出现个数
3.示例:
#include<iostream>
#include<map>
using namespace std;
void test01()
{
//查找
map<int, int>m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(2, 20));
map<int, int>::iterator pos = m.find(3);//find返回迭代器
if (pos != m.end())
{
cout << "找到元素key = " << (*pos).first << " value" << pos->second << endl;
}
else
{
cout << "未找到元素" << endl;
}
//统计
// map不允许插入重复key 对于count统计结果要么0,要么1
//multimap允许插入重复key 对于count统计结果可以大于1
int num = m.count(3);
cout << "num = " << num << endl;
multimap<int, int> m2;
m2.insert(pair<int, int>(1, 10));
m2.insert(pair<int, int>(1, 10));
m2.insert(pair<int, int>(1, 10));
int num2 = m2.count(1);
cout << "num2 = " << num2 << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
五、map容器排序
1.学习目标:map容器默认排序规则为? 按照key值进行从小到大排序,学习如何改变排序规则
2.技术要点:
- 利用仿函数,可以改变排序规则
3.示例一:内置数据类型排序
#include<iostream>
#include<map>
using namespace std;
class myCompare
{
public:
bool operator()(int v1, int v2) const
{
//降序
return v1 > v2;
}
};
void test01()
{
map<int, int>m;
m.insert(make_pair(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(5, 50));
m.insert(make_pair(3, 30));
m.insert(make_pair(4, 40));
cout << "默认从小到大排序:" << endl;
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key = " << it->first << " value" << it->second << endl;
}
cout << endl;
map<int, int, myCompare>m2;
m2.insert(make_pair(1, 10));
m2.insert(make_pair(2, 20));
m2.insert(make_pair(5, 50));
m2.insert(make_pair(3, 30));
m2.insert(make_pair(4, 40));
cout << "改变从大到小排序:" << endl;
for (map<int, int, myCompare>::iterator it = m2.begin(); it != m2.end(); it++)
{
cout << "key = " << it->first << " value" << it->second << endl;
}
cout << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
3.示例二:自定义数据类型排序
#include<iostream>
#include<map>
using namespace std;
class Person
{
public:
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
class myCompare
{
public:
bool operator()(int v1, int v2) const
{
return v1 > v2;
}
};
void test01()
{
map<int, Person> f;
Person p1("刘备", 24);
Person p2("小阿备", 2);
Person p3("关羽", 20);
Person p4("小阿飞", 3);
f.insert(make_pair(1, p1));
f.insert(make_pair(4, p4));
f.insert(make_pair(3, p3));
f.insert(make_pair(2, p2));
cout << "----------默认排序----------" << endl;
for (map<int, Person>::iterator it = f.begin(); it != f.end(); it++)
{
cout << "key = " << it->first << " 姓名:" << it->second.m_Name << " 年龄:" << it->second.m_Age << endl;
}
cout << endl;
cout << "----------从大到小排序----------" << endl;
map<int, Person, myCompare> f2; //只能按照key值排序
Person p11("刘备", 24);
Person p12("小阿备", 2);
Person p13("关羽", 20);
Person p14("小阿飞", 3);
f2.insert(make_pair(1, p11));
f2.insert(make_pair(4, p14));
f2.insert(make_pair(3, p13));
f2.insert(make_pair(2, p12));
for (map<int, Person, myCompare>::iterator it = f2.begin(); it != f2.end(); it++)
{
cout << "key = " << it->first << " 姓名:" << it->second.m_Name << " 年龄:" << it->second.m_Age << endl;
}
cout << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
总结:自定义数据类型也只能按照key值排序,不能按照Person的年龄排序。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!