文章目录
set / multiset构造 和 赋值set大小和交换set插入和删除set查好和统计set 和 multiset 的区别pair对组的创建set容器排序内置数据类型自定义数据类型
map / multimap
map容器的构造和赋值map的大小和交换map插入和删除查找和统计map排序内置数据类型自定义数据类型
STL案例--员工分组
set / multiset
所有元素在插入式就会自动排好序set 和 multiset都是关联式容器, 底层是二叉树实现set 和 multiset的区别
set 中不允许有重复元素 (插入重复数据也不会报错, 只是不在里面)multiset 可以有重复元素
构造 和 赋值
void printSet(const set
<int>& s
) {
for(auto it
= s
.begin(); it
!= s
.end(); it
++) {
cout
<<(*it
)<<endl
;
}
}
void test01() {
set
<int> s1
;
s1
.insert(10);
s1
.insert(30);
s1
.insert(40);
s1
.insert(10);
s1
.insert(20);
printSet(s1
);
cout
<<endl
;
set
<int> s2(s1
);
printSet(s2
);
cout
<<endl
;
set
<int> s3
;
s3
= s1
;
printSet(s3
);
}
int main() {
test01();
return 0;
}
set大小和交换
swap(s1, s2), s1.swap(s2) 均可不可以指定大小, 因为默认填充的话就有重复0了
set插入和删除
set查好和统计
count()函数, 对于set而言只有0或1, multiset才有多种可能用count更好判断某个元素在不在set中
auto it
= s1
.find(40);
if (it
== s1
.end())
cout
<<"wei zhao dao"<<endl
;
else
cout
<<(*it
)<<endl
;
set 和 multiset 的区别
. 运算符的优先级 和 括号是同一级的
set
<int> s1
;
pair
<set
<int>::iterator
, bool> p1
= s1
.insert(10);
cout
<<(*(p1
.first
))<<" "<<p1
.second
<<endl
;
pair
<set
<int>::iterator
, bool> p2
= s1
.insert(10);
cout
<<(*(p2
.first
))<<" "<<p2
.second
<<endl
;
cout
<<endl
;
multiset
<int> s2
;
auto it1
= s2
.insert(10);
cout
<<(*it1
)<<endl
;
auto it2
= s2
.insert(10);
cout
<<(*it2
)<<endl
;
pair对组的创建
成对出现的数据, 利用对组可以一次性返回两个数据
pair
<string
, int> p1
= make_pair("yyy", 20);
pair
<string
, int> p2("yw", 40);
cout
<<p1
.first
<<" "<<p1
.second
<<endl
;
cout
<<p2
.first
<<" "<<p2
.second
<<endl
;
set容器排序
set容器默认排序从小到大, 如何变成从大到小?利用仿函数, 改变排序规则, 必须在插入之前就改变排序规则仿函数实际上是一种数据类型, 重载()运算符. 最后需要加上const, 表明不能在函数内部修改变量
内置数据类型
class MyCmp
{
public:
bool operator() (int n
, int m
) const{
return n
> m
;
}
};
void test03() {
set
<int, MyCmp
> s
;
s
.insert(10);
s
.insert(20);
s
.insert(30);
s
.insert(40);
for(auto it
= s
.begin(); it
!= s
.end(); it
++) {
cout
<<*it
<<endl
;
}
}
自定义数据类型
class Person
{
public:
string name
;
int age
;
Person(string name
, int age
) : name(name
), age(age
) {}
};
class MyComp
{
public:
bool operator() (const Person
& p1
, const Person
& p2
) const{
return p1
.age
> p2
.age
;
}
};
void test04() {
set
<Person
, MyComp
> s
;
s
.insert(Person("y", 21));
s
.insert(Person("yy", 22));
s
.insert(Person("yyy", 23));
s
.insert(Person("yyyyy", 24));
for (auto it
= s
.begin(); it
!= s
.end(); it
++) {
cout
<<"name : "<<it
->name
<<"\tage : "<<it
->age
<<endl
;
}
}
map / multimap
map中所有元素都是pair
pair中第一个元素为key(键), 第二个元素为value(实值)
所有元素都会根据元素的键值自动排序
map/multimap 属于关联式容器, 底层结构也是用二叉树实现
优点 (高效): 可以根据key值快速找到value值
map 和 multimap的区别
map不允许容器中有重复key值元素(但是value值可以重复)multimap中允许容器中有重复key值元素
map容器的构造和赋值
#include <iostream>
#include <map>
using namespace std
;
void printMap(const map
<int, int>& m
) {
for(map
<int, int>::const_iterator it
= m
.begin(); it
!= m
.end(); it
++) {
cout
<<it
->first
<<"\t"<<it
->second
<<endl
;
}
}
void test01
() {
map
<int, int> m
;
m
.insert(make_pair(1, 10));
m
.insert(make_pair(4, 40));
m
.insert(make_pair(3, 30));
m
.insert(make_pair(2, 20));
printMap(m
);
cout
<<endl
;
map
<int, int> m2(m
);
printMap(m2
);
cout
<<endl
;
map
<int, int> m3
;
m3
= m2
;
printMap(m3
);
}
int main() {
test01();
return 0;
}
1 10
2 20
3 30
4 40
1 10
2 20
3 30
4 40
1 10
2 20
3 30
4 40
map的大小和交换
map插入和删除
void test02() {
map
<int, int> m
;
m
.insert(pair
<int, int>(1, 10));
m
.insert(make_pair(2,20));
m
.insert(map
<int, int>::value_type(3, 30));
m
[4] = 40;
printMap(m
);
cout
<<endl
<<m
[5]<<endl
<<endl
;
printMap(m
);
}
1 10
2 20
3 30
4 40
0
1 10
2 20
3 30
4 40
5 0
Program ended with exit code
: 0
不建议用第四种中括号的方式插入
如果没找到key为5的值, 他会自动创建一个(5, 0)的组对插入
可以用中括号获取key对应的value的值
insert() 函数也返回一个pair组队, 第一个元素是插入成功的key值, 第二个是bool
查找和统计
void test02() {
map
<int, int> m
;
m
.insert(pair
<int, int>(1, 10));
m
.insert(make_pair(2,20));
pair
<map
<int, int>::iterator
, bool> it
= m
.insert(map
<int, int>::value_type(3, 30));
cout
<<(it
.first
)->second
<<endl
;
m
[4] = 40;
auto it2
= m
.find(3);
if (it2
== m
.end())
cout
<<"no"<<endl
;
else
cout
<<"key: "<<it2
->first
<<"\tvalue: "<<(*it2
).second
<<endl
;
unsigned long num
= m
.count(2);
cout
<<"num: "<<num
<<endl
;
}
30
key
: 3 value
: 30
num
: 1
map的count只能是0或1, 后面的相同key的插入不进去multimap的count函数才可能大于1
map排序
利用仿函数, 改变map排序规则 , 但是只能根据键值排序即使map存的是键值对, 仿函数仍然是两个参数, 传入的两个键值
内置数据类型
class MyCompare
{
public:
bool operator() (int v1
, int v2
) const
{
return v1
> v2
;
}
};
void test03() {
map
<int, int, MyCompare
> m
;
m
.insert(make_pair(1, 50));
m
.insert(make_pair(2, 40));
m
.insert(make_pair(3, 30));
m
.insert(make_pair(4, 20));
m
.insert(make_pair(5, 10));
for (map
<int, int, MyCompare
>::iterator it
= m
.begin(); it
!= m
.end(); it
++) {
cout
<<"key: "<<it
->first
<<"\tvalue: "<<it
->second
<<endl
;
}
}
自定义数据类型
class MyCompare
{
public:
bool operator() (Person p1
, Person p2
) const
{
return p1
.age
> p2
.age
;
}
};
void test03() {
map
<Person
, int, MyCompare
> m
;
m
.insert(make_pair(Person("y", 1), 50));
m
.insert(make_pair(Person("yy", 2), 40));
m
.insert(make_pair(Person("yyy", 3), 30));
m
.insert(make_pair(Person("yyyy", 4), 20));
m
.insert(make_pair(Person("yyyyy", 5), 10));
for (map
<Person
, int, MyCompare
>::iterator it
= m
.begin(); it
!= m
.end(); it
++) {
cout
<<"key: \nname: "<<it
->first
.name
<<" age: "<<it
->first
.age
<<"\nvalue: "<<it
->second
<<endl
;
}
}
STL案例–员工分组
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <ctime>
using namespace std
;
#define CEHUA 0
#define XUANCHUAN 1
#define YANFA 2
class Worker
{
public:
string name
;
int salary
;
};
void createWorkers(vector
<Worker
>& vWorker
) {
string nameSeed
= "ABCDEFGHIJ";
for (int i
= 0; i
< 10; i
++) {
Worker w
;
w
.name
= "员工";
w
.name
+= nameSeed
[i
];
w
.salary
= rand() % 10001 + 10000;
vWorker
.push_back(w
);
}
}
void getGroup(vector
<Worker
>& w
, multimap
<int, Worker
>& m
) {
string nameSeed
= "ABCDEFGHIJ";
for (int i
= 0; i
< 10; i
++) {
int num
= rand() % 3 + 1;
m
.insert(make_pair(num
, w
[i
]));
}
}
void showWorkers(multimap
<int, Worker
>& m
) {
cout
<<"策划: "<<endl
;
multimap
<int, Worker
>::iterator pos
= m
.find(CEHUA
);
unsigned long num
= m
.count(CEHUA
);
int index
= 0;
for (;pos
!= m
.end() && index
< num
; pos
++, index
++) {
cout
<<pos
->second
.name
<<"\t"<<(*pos
).second
.salary
<<endl
;
}
cout
<<"---------------------------"<<endl
;
cout
<<"宣传: "<<endl
;
pos
= m
.find(YANFA
);
num
= m
.count(YANFA
);
index
= 0;
for (;pos
!= m
.end() && index
< num
; pos
++, index
++) {
cout
<<pos
->second
.name
<<"\t"<<(*pos
).second
.salary
<<endl
;
}
cout
<<"---------------------------"<<endl
;
cout
<<"研发: "<<endl
;
pos
= m
.find(XUANCHUAN
);
num
= m
.count(XUANCHUAN
);
index
= 0;
for (;pos
!= m
.end() && index
< num
; pos
++, index
++) {
cout
<<pos
->second
.name
<<"\t"<<(*pos
).second
.salary
<<endl
;
}
cout
<<endl
;
}
int main() {
srand((unsigned int)time(NULL));
vector
<Worker
> vWorker
;
createWorkers(vWorker
);
multimap
<int, Worker
> m
;
getGroup(vWorker
, m
);
showWorkers(m
);
return 0;
}