文章目录
set/multiset容器
基本概念:
所有元素都会在插入的时候自动被排序
本质:
属于关联式容器,底层用二叉树实现
头文件
#include<set>
在set 容器中,不可以插入重复的数据,如果插入了,也是白插,不会存储在容器中。
构造:
- 默认构造
- 拷贝构造
赋值:
- = 赋值操作
大小和交换
- size()
- empty()
- swap(st) 交换两个set容器
插入和删除
- insert(elem)在容器中插入元素
- clear()清空所有元素
- erase(pos)删除pos迭代器所指的的数据
- erase(beg,end) 删除区间[beg,end)的所有元素
- erase(elem )删除容器中的elem元素
查找和统计
- fine(key) 查找key是否存在,返回值为一个迭代器
- count(key) 统计key元素的个数
#include<iostream>
#include<set>
using namespace std;
void printSet(set<int >& s)
{
for (set<int>::iterator se = s.begin(); se != s.end(); se++)
{
cout << *se << ' ';
}
cout << endl;
}
void test01()
{
set<int > s;
set<int > s1;
//向容器s中添加数据
s.insert(10);
s.insert(20);
s.insert(30);
s.insert(70);
s.insert(40);
//输出s容器
printSet(s);
//输出s容器大小
cout << "容器大小为:" << s.size()<< endl;
//向容器s1中添加数据
s1.insert(50);
s1.insert(60);
s1.insert(20);
s1.insert(36);
s1.insert(85);
//输出s1中的内容
printSet(s1);
//交换s和s1的数据元素
s.swap(s1);
//输出交换后的容器数据
cout << "交换后s容器中的内容:";
printSet(s);
cout << "交换后s1容器中的内容:";
printSet(s1);
//删除操作
cout << "删除操作:" << endl;
//删除某个迭代器所指位置的内容
s.erase(s.begin());
cout << "删除s中s.begin()之后容器的内容" << endl;
printSet(s);
cout << "删除区间[s1.begin(),s1.end())之后容器剩余的数据" << endl;
s1.erase(s1.begin(), s1.end());
printSet(s1);
//查找
set<int>::iterator it = s.find(10);
if (it == s.end())
{
cout << "数据不存在" << endl;
}
else {
cout << *it << endl;
}
//统计元素个数
//对于set而言,统计的结果要么是0要么是1,
//这个主要是用于multiset,multiset中可以有重复元素
cout << "查找36在set中出现的次数:" << s.count(36) << endl;
}
int main()
{
test01();
}
set和multiset的区别
- set不可以插入重复的数据,但是multiset可以
- set插入数据时会返回先插入结果,表示是否插入成功
- multiset不会检测数据,因此可以重复插入数据
void printMultiset(multiset<int >& s)
{
for (multiset<int>::iterator se = s.begin(); se != s.end(); se++)
{
cout << *se << ' ';
}
cout << endl;
}
void test02()
{
multiset<int> mul;
mul.insert(10);
mul.insert(10);
mul.insert(10);
mul.insert(10);
printMultiset(mul);
}
int main()
{
//test01();
test02();
}
输出结果
pair对组的创建和使用
概念:
成对出现的数据,包括两个数据,利用对组可以返回两个数据
void test03()
{
//第一种创建方式
pair<string, int> stu("tom", 18);
//第二种创建方式
pair<string, int> st = make_pair("Alice",18);
cout << stu.first<< ' '<< stu.second << endl;
cout << st.first<< ' '<< st.second << endl;
}
int main()
{
//test01();
//test02();
test03();
}
set容器排序
set容器默认为从小到大的排序,这里讲述怎么改变这种默认排序
利用仿函数,改变排序的规则
//利用仿函数修改set容器的规则
class Compare
{
public:
bool operator()(int v1, int v2)const
{
return v1 > v2;
}
};
void test04()
{
//规则需要在添加数据之前设置
set<int,Compare> s;
s.insert(12);
s.insert(62);
s.insert(22);
s.insert(62);
s.insert(6);
s.insert(98);
for (set<int,Compare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << ' ';
}
}
int main()
{
//test01();
//test02();
//test03();
test04();
}
set容器添加自定义数据类型
set不能识别自定义类型的大小,需要自己设置排序规则
就需要重载operator()设置排序规则
class Dog
{
public :
Dog(string name, int age)
{
this->name = name;
this->age = age;
}
string name;
int age;
};
//仿函数重载
class Compare
{
public:
bool operator()(const Dog d1, const Dog d2)const
{
return d1.age > d2.age;
}
};
void test05()
{
set<Dog, Compare> s;
Dog d1("小黄",2);
Dog d2("小白",3);
Dog d3("小蓝",1);
Dog d4("小红",5);
s.insert(d1);
s.insert(d2);
s.insert(d3);
s.insert(d4);
//输出
for (set<Dog, Compare>::iterator it = s.begin(); it != s.end(); it++)
{
cout << it->name <<' ' << it->age << endl;
}
}
int main()
{
//test01();
//test02();
//test03();
//test04();
test05();
}
map/multimap容器
基本概念
- map中所有的元素都是pair
- pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)
- 所有元素都会根据元素的键值(key)自动排序
- 本质上是关联式容器,底层是用二叉树实现
优点:
- 可以根据不同的key值找到value值
map与multimap的区别:
- map不允许容器中有重复的key值
- multimap允许容器中有重复的key值
构造
- 默认构造
- 拷贝构造
赋值
- = 赋值
void printMap(map<int, int>& m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key" << it->first << '\t' << "value" << it->second << endl;
}
}
void test06()
{
//默认构造
//两个参数指定key和value的类型
map<int,int> m;
m.insert(pair<int,int>(-1,10));
m.insert(pair<int,int>(2,20));
m.insert(pair<int,int>(3,30));
m.insert(pair<int,int>(4,40));
printMap(m);
//拷贝构造
map<int, int>m2 = m;
printMap(m2);
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
test06();
}
大小和交换
- size() 返回容器数据数目
- empty() 容器是否为空
- swap(ma) 交换两个容器
插入和删除
- insert(elem) 每个元素都是对组
- clear()清空
- erase(pos ) 删除POS迭代器所指的数据
- erase(beg,end) 删除区间内容
- erase(key)删除值为key的元素
//四种插入数据方式
//第一种
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));
printMap(m1);
//第四种 不推荐用来插入数据
// 可用来访问数据
//如下,key值为4,value为40;
m1[4] = 40;
查找和统计
- find(key) 返回键值为key 的迭代器,如果不存在,返回end()迭代器
- count(key) 对于map只能返回0或1,multimap返回的值可能会大于1
排序
默认顺序根据key值从小到大排序
利用仿函数,改变排序规则
//修改排序规则
class MyCompare
{
public:
bool operator()(int v1,int v2)const
{
return v1 > v2;
}
};
void printMap2(map<int, int,MyCompare>& m)
{
for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
{
cout << "key" << ' ' << it->first << '\t' << "value" << ' ' << it->second << endl;
}
}
void test07()
{
map<int, int,MyCompare> m;
m.insert(pair<int, int>(1, 10));
m.insert(pair<int, int>(2, 20));
m.insert(pair<int, int>(3, 30));
m.insert(pair<int, int>(4, 40));
printMap2(m);
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
test07();
}
函数对象
概念:
重载了函数调用操作符的类,其对象通常称为函数对象
函数对象使用重载的()时,行为类似函数调用,也叫仿函数
本质:
本质是一个类,不是一个函数
特点:
- 函数对象在使用时,可以像普通函数那样调用 ,可以有参数,也可以有返回值
- 函数对象可以有自己的状态
- 函数对象可以作为参数传递
//可以像普通函数调用
class Sum
{
public:
int operator()(int v1, int v2)
{
return v1 + v2;
}
};
void test08()
{
Sum sum;
int a = sum(10, 23);
cout << a;
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
//test07();
test08();
}
//可以作为参数传递
class Print
{
public:
void operator()(string name)
{
cout << name << endl;
}
};
void DoPrint(Print& P, string name)
{
P(name);
}
void test09()
{
Print P;
DoPrint(P, "小黄");
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
//test07();
//test08();
test09();
}
谓词
概念
- 返回bool类型的仿函数称为谓词
- 如果operator()接受一个参数,叫做一元谓词
- 如果operator()接受两个参数,叫做二元谓词
一元谓词案例
//查找大于10 的数字
class GraterTen
{
public :
bool operator()(int val)
{
return val > 10;
}
};
void test10()
{
vector<int> v;
v.push_back(23);
v.push_back(2);
v.push_back(3);
v.push_back(15);
v.push_back(16);
//find_if在vector容器中查找大于10的数值,如果找到,返回迭代器
//GraterTen()创建匿名对象,这个是用来判断数据是否大于10
vector<int> ::iterator it = find_if(v.begin(), v.end(), GraterTen());
cout << *it;
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
//test07();
//test08();
//test09();
test10();
}
二元谓词案例
//改变排序规则
class compare
{
public:
bool operator()(int val1, int val2)
{
return val1 > val2;
}
};
void test11()
{
vector<int> v;
v.push_back(15);
v.push_back(32);
v.push_back(25);
v.push_back(55);
//compare()创建匿名对象
sort(v.begin(), v.end(), compare());
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << ' ';
}
cout << endl;
}
int main()
{
//test01();
//test02();
//test03();
//test04();
//test05();
//test06();
//test07();
//test08();
//test09();
//test10();
test11();
}