#2020/03/10
day01至day05完结
1.map容器
此处不再对函数具体介绍,可进入Cpp参考
#include <iostream>
#include <map>
using namespace std;
//map容器初始化
void test01(){
//map容器模板参数,第一个参数key的类型,第二参数value类型
map<int, int> mymap;
//插入数据 pair.first key值 piar.second value值
//第一种
pair<map<int, int>::iterator, bool> ret = mymap.insert(pair<int, int>(10, 10));
//iterator表示插入的位置
if (ret.second){
cout << "第一次插入成功!" << endl;
}
else{
cout << "插入失败!" << endl;
}
ret = mymap.insert(pair<int, int>(10, 20));
if (ret.second){
cout << "第二次插入成功!" << endl;
}
else{
cout << "插入失败!" << endl;
}
//第二种
mymap.insert(make_pair(20, 20));
//第三种
mymap.insert(map<int, int>::value_type(30,30));
//第四种
mymap[40] = 40;
mymap[10] = 20;
mymap[50] = 50;
//发现如果key不存在,创建pair插入到map容器中
//如果发现key存在,那么会修改key对应的value
//打印
for (map<int, int>::iterator it = mymap.begin(); it != mymap.end();it ++){
// *it 取出来的是一个pair
cout << "key:" << (*it).first << " value:" << it->second << endl;
}
//如果通过[]方式去访问map中一个不存在key,
//那么map会将这个访问的key插入到map中,并且给value一个默认值
cout << " mymap[60]: " << mymap[60] << endl;
//打印
for (map<int, int>::iterator it = mymap.begin(); it != mymap.end(); it++){
// *it 取出来的是一个pair
cout << "key:" << (*it).first << " value:" << it->second << endl;
}
}
class MyKey{
public:
MyKey(int index,int id){
this->mIndex = index;
this->mID = id;
}
public:
int mIndex;
int mID;
};
struct mycompare{
bool operator()(MyKey key1, MyKey key2){
return key1.mIndex > key2.mIndex;
}
};
void test02(){
map<MyKey, int, mycompare> mymap; //自动排序,自定数据类型,咋排?
mymap.insert(make_pair(MyKey(1, 2), 10));
mymap.insert(make_pair(MyKey(4, 5), 20));
for (map<MyKey, int, mycompare>::iterator it = mymap.begin(); it != mymap.end();it ++){
cout << it->first.mIndex << ":" << it->first.mID << " = " << it->second << endl;
}
}
//equal_range
void test03(){
map<int, int> mymap;
mymap.insert(make_pair(1, 4));
mymap.insert(make_pair(2, 5));
mymap.insert(make_pair(3, 6));
pair<map<int, int>::iterator, map<int, int>::iterator> ret = mymap.equal_range(2);
if (ret.first != mymap.end()){
cout << "找到lower_bound!" << endl;
}
else{
cout << "没有找到";
}
if (ret.second != mymap.end()){
cout << "找到upper_bound!" << endl;
}
else{
cout << "没有找到";
}
}
int main(void){
//test01();
//test02();
test03();
return 0;
}
2.multimap容器
multimap案例_员工分组
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <time.h>
#include <stdlib.h>
using namespace std;
#define SALE_DEPATMENT 1 //销售部门
#define DEVELOP_DEPATMENT 2 //研发部门
#define FINACIAL_DEPATMENT 3 //财务部门
//multimap 案例
//公司今天招聘了 5 个员工, 5 名员工进入公司之后,需要指派员工在那个部门工作
//人员信息有: 姓名 年龄 电话 工资等组成
//通过 Multimap 进行信息的插入 保存 显示
//分部门显示员工信息 显示全部员工信息
class Worker{
public:
string mName;
string mTele;
int mAge;
int mSalary;
};
void Create_Worker(vector<Worker>& vWorker){
string seedName = "ABCDE";
for (int i = 0; i < 5;i ++){
Worker worker;
worker.mName = "员工";
worker.mName += seedName[i];
worker.mAge = rand() % 10 + 20;
worker.mTele = "010-8888888";
worker.mSalary = rand() % 10000 + 10000;
//保存员工信息
vWorker.push_back(worker);
}
}
//员工分组
void WorkerByGroup(vector<Worker>& vWorker, multimap<int, Worker>& workerGroup){
//把员工随机分配不同部门
srand(time(NULL));
for (vector<Worker>::iterator it = vWorker.begin(); it != vWorker.end();it ++){
int departID = rand() % 3 + 1;
switch (departID){
case SALE_DEPATMENT:
workerGroup.insert(make_pair(SALE_DEPATMENT,*it));
break;
case DEVELOP_DEPATMENT:
workerGroup.insert(make_pair(DEVELOP_DEPATMENT, *it));
break;
case FINACIAL_DEPATMENT:
workerGroup.insert(make_pair(FINACIAL_DEPATMENT, *it));
break;
default:
break;
}
}
}
void ShowGroupWorkers(multimap<int, Worker>& workerGroup, int departID){
multimap<int, Worker>::iterator it = workerGroup.find(departID);
//找当前部门总人数
int DepartCount = workerGroup.count(departID);
int num = 0;
for (multimap<int, Worker>::iterator pos = it; it != workerGroup.end() && num <
DepartCount; pos++, num++){
cout << "姓名:" << pos->second.mName << " 年龄:" << pos->second.mAge << " 电话:" <<
pos->second.mTele << " 工资:" << pos->second.mSalary << endl;
}
}
//打印每一部分员工信息
void PrintWorkerByGroup(multimap<int, Worker>& workerGroup){
//打印销售部员工信息
//显示销售部门
cout << "销售部门:" << endl;
ShowGroupWorkers(workerGroup,SALE_DEPATMENT);
//显示开发部门
cout << "研发部门:" << endl;
ShowGroupWorkers(workerGroup, DEVELOP_DEPATMENT);
//显示财务部门
cout << "财务部门:" << endl;
ShowGroupWorkers(workerGroup, FINACIAL_DEPATMENT);
}
int main(void){
//存放新员工的信息
vector<Worker> vWorker;
//multimap保存分组信息
multimap<int, Worker> workerGroup;
//创建员工
Create_Worker(vWorker);
//员工分组
WorkerByGroup(vWorker, workerGroup);
//打印每一部分员工信息
PrintWorkerByGroup(workerGroup);
return 0;
}
3.容器深拷贝和浅拷贝
深拷贝和浅拷贝的区别如下图所示:
#include <iostream>
#include <vector>
using namespace std;
class Person{
public:
Person(char* name,int age){
this->pName = new char[strlen(name) + 1];
strcpy(this->pName, name);
this->mAge = age;
}
Person(const Person& p){
this->pName = new char[strlen(p.pName) + 1];
strcpy(this->pName, p.pName);
this->mAge = p.mAge;
}
Person& operator=(const Person& p){ // 该重载函数用于解决浅拷贝问题
if (this->pName != NULL){
delete[] this->pName;
}
this->pName = new char[strlen(p.pName) + 1];
strcpy(this->pName, p.pName);
this->mAge = p.mAge;
return *this;
}
~Person(){
if (this->pName != NULL){
delete[] this->pName;
}
}
public:
char* pName; //指针 容易浅拷贝的问题
int mAge;
};
void test01(){
Person p("aaa",20);
vector<Person> vPerson;
vPerson.push_back(p); //实际上p被拷贝进vector容器之中,浅复制会导致一次构造、两次析构
}
int main(void){
test01();
return 0;
}
4.函数对象
具体用法看test01()中的注释及下方代码示例:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct MyPrint{ //函数对象(仿函数)
MyPrint(){
mNum = 0;
}
void operator()(int val){
mNum++;
cout << val << endl;
}
public:
int mNum;
};
int num = 0; //真正开发中,尽量避免去使用全局变量 加锁解锁
void MyPrint02(int val){
num++;
cout << val << endl;
}
void test01(){
MyPrint print;
print(10);
//函数对象可以像普通函数一样调用
//函数对象可以像普通函数那样接收参数
//函数对象超出了函数的概念,函数对象可以保存函数调用的状态
}
void test02(){
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
//计算函数调用次数
#if 0
MyPrint02(10);
MyPrint02(20);
cout << num << endl;
MyPrint print;
print(10);
print(20);
cout << print.mNum << endl;
#endif
MyPrint print;
MyPrint& print02 = for_each(v.begin(), v.end(), print); // 原理可参考for_each()的定义
cout << "print调用次数:" << print.mNum << endl;
cout << "print调用次数:" << print02.mNum << endl; //显示真正的调用次数
}
int main(void){
test02();
return 0;
}
5.内建函数对象
内建函数不需要自己定义,可以直接新建函数对象
#include <iostream>
#include <functional>
using namespace std;
void test01(){
plus<int> myplus;
cout << myplus(10, 20) << endl;
}
int main(void){
test01();
return 0;
}
6.函数对象适配器
具体见代码注释
#include <iostream>
#include<vector>
#include<functional>
#include<algorithm>
using namespace std;
//如果要适配,一定要继承binary_function<...>
struct MyPrint : public binary_function<int,int,void> {
// binary_function<int, int, void>中的void与operator()的返回类型相同
// <int, int, void>的int, int与operator()(int, int)相同
void operator()(int v,int val) const{
cout << "v:" << v << " val:" << val << endl;
cout << v + val << " ";
}
};
//仿函数适配器 bind1st bind2nd 绑定适配器
void test01(){
vector<int> v;
for (int i = 0; i < 10;i ++){
v.push_back(i);
}
int addNum = 200;
for_each(v.begin(), v.end(), bind1st(MyPrint(), addNum));
//绑定适配器 将一个二元函数对象转变成一元函数对象
//bind1st bind2nd区别?
//bind1st,将addNum绑定为函数对象的第一个参数
//bind2nd,将addNum绑定为函数对象的第二个参数
}
struct MyPrint02{
void operator()(int v){
cout << v << " ";
}
};
struct MyCompare : public binary_function<int,int,bool>{
bool operator()(int v1, int v2) const{
return v1 > v2;
}
};
struct MyGreater5 : public binary_function<int,int,bool>{ //operator()(int)用unary_function<int, bool>
bool operator()(int v,int val) const{
cout << "v:" << v << " val:" << val << endl;
return v < val;
}
};
//仿函数适配器 not1 not2 取反适配器
void test02(){
vector<int> v;
for (int i = 0; i < 10; i++){
v.push_back(i);
}
for_each(v.begin(), v.end(), MyPrint02()); cout << endl;
sort(v.begin(), v.end(), not2(MyCompare()));
for_each(v.begin(), v.end(), MyPrint02()); cout << endl;
//not1 not2
//如果对二元谓词取反,用not2
//如果对一元谓词取反,用not1
vector<int>::iterator it = find_if(v.begin(), v.end(),not1(bind2nd(MyGreater5(),5)));
if (it == v.end()){
cout << "没有找到" << endl;
}
else{
cout << *it << endl;
}
}
//仿函数适配器 ptr_fun
void MyPrint03(int val,int val2){
cout << "val1:" << val << " val2:" << val2 << endl;
cout << val + val2 << endl;
}
void test03(){
vector<int> v;
for (int i = 0; i < 10; i++){
v.push_back(i);
}
//ptr_func把普通函数 转成 函数对象
for_each(v.begin(), v.end(), bind2nd(ptr_fun(MyPrint03),10));
}
//成员函数适配器 mem_fun mem_fun_ref
class Person{
public:
Person(int age, int id) :age(age), id(id){}
void show(){
cout << "age:" << age << " id:" << id << " aaa" << endl;
}
public:
int age;
int id;
};
void test04(){
//如果容器中存放的对象或者对象指针,我们for_each算法打印的时候,调用类
//自己提供的打印函数,for_each()既可以接受普通函数也可以接受函数对象
vector<Person> v;
Person p1(10, 20), p2(30, 40), p3(50, 60);
v.push_back(p1);
v.push_back(p2);
v.push_back(p3);
//格式: &类名::函数名
for_each(v.begin(), v.end(), mem_fun_ref(&Person::show));
vector<Person*> v1;
v1.push_back(&p1);
v1.push_back(&p2);
v1.push_back(&p3);
for_each(v1.begin(),v1.end(),mem_fun(&Person::show));
//mem_fun_ref mem_fun区别?
//如果存放的是对象指针 使用mem_fun
//如果使用的是对象 使用mem_fun_ref
}
int main(void){
//test01();
//test02();
//test03();
test04();
return 0;
}
7.常用的遍历算法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//transform 将一个容器的元素 搬运 到另一个容器中
struct MyPlus{
int operator()(int val){
return val + 100;
}
};
void MyPrint(int val){
cout << val << " ";
}
void test01(){
vector<int> v1;
vector<int> v2;
for (int i = 0; i < 10;i++){
v1.push_back(i);
}
v2.resize(v1.size()); //开辟空间
//v1.begin()到v1.end()的值依次传给MyPlus(),MyPlus的返回值再传给v2
transform(v1.begin(), v1.end(), v2.begin(), MyPlus());
for_each(v2.begin(), v2.end(), MyPrint);
cout << endl;
}
//常用的查找算法
void test02(){
vector<int> v1;
for (int i = 0; i < 10; i++){
v1.push_back(i);
}
vector<int>::iterator ret = find(v1.begin(), v1.end(), 5);
if (ret == v1.end()){
cout << "么有找到!" << endl;
}
else{
cout << "找到了:" << *ret << endl;
}
}
class Person{
public:
Person(int age, int id) :age(age), id(id){}
bool operator==(const Person& p) const{
return p.id == this->id && p.age == this->age;
}
public:
int id;
int age;
};
void test03(){
vector<Person> v1;
Person p1(10, 20), p2(20, 30);
v1.push_back(p1);
v1.push_back(p2);
vector<Person>::iterator ret = find(v1.begin(), v1.end(), p1);
if (ret == v1.end()){
cout << "么有找到!" << endl;
}
else{
cout << "找到了:" << endl;
}
}
//binary_search 二分查找法
bool MySearch(int val){
return val > 5;
}
bool MySearch2(int val){
return val > 5;
}
void test04(){
vector<int> v1;
for (int i = 0; i < 10; i++){
v1.push_back(i);
}
v1.push_back(9);
bool ret =binary_search(v1.begin(), v1.end(), 5);
if (ret){
cout << "找到!" << endl;
}else{
cout << "没有找到!" << endl;
}
vector<int>::iterator it = adjacent_find(v1.begin(), v1.end());
if (it != v1.end()){
cout << "找到相邻重复元素:" << *it << endl;
}
else{
cout << "没有找打相邻重复元素" << endl;
}
//find_if 会根据我们的条件(函数) ,返回第一个满足条件的元素的迭代器
it = find_if(v1.begin(), v1.end(), MySearch);
if (it != v1.end()){
cout << "找到:" << *it << endl;
}
else{
cout << "没有找到" << endl;
}
//count count_if
int num = count(v1.begin(), v1.end(), 9);
cout << "9出现的次数:" << num << endl;
num = count_if(v1.begin(), v1.end(), MySearch2);
cout << "大于5的个数:" << num << endl;
}
int main(void){
//test01();
//test02();
//test03();
test04();
return 0;
}
来源:CSDN
作者:百事_可乐
链接:https://blog.csdn.net/qq_40817333/article/details/104703048