01 上次课程回顾
昨天讲了三个容器
string string是对char*进行的封装
vector 单口容器 动态数组
deque(双端队列)
函数对象/谓词:
一元函数对象:
for_each:
谓词: predicate
一元谓词:
find_if
二元函数对象: transform
transform操作: 两个容器相加 放到第三个
class myplus {
public:
int operator()(int v1,int v2){
return v1 + v2;
}
private:
};
void test03() {
vector
for (int i = 0; i < 10; i++)
{
v1.push_back(i);
v2.push_back(i+1);
}
/*
template class _InIt2, class _OutIt, class _Fn> inline _OutIt transform(const _InIt1 _First1, const _InIt1 _Last1, const _InIt2 _First2, _OutIt _Dest, _Fn _Func) { // transform [_First1, _Last1) and [_First2, ...) with _Func _Adl_verify_range(_First1, _Last1); auto _UFirst1 = _Get_unwrapped(_First1); const auto _ULast1 = _Get_unwrapped(_Last1); const auto _Count = _Idl_distance<_InIt1>(_UFirst1, _ULast1); auto _UFirst2 = _Get_unwrapped_n(_First2, _Count); auto _UDest = _Get_unwrapped_n(_Dest, _Count); for (; _UFirst1 != _ULast1; ++_UFirst1, (void)++_UFirst2, ++_UDest) { *_UDest = _Func(*_UFirst1, *_UFirst2); ←!最后的处理,这里是二元函数对象 } _Seek_wrapped(_Dest, _UDest); return (_Dest); } v1+v2 放到v3的开始位置 */ v3.resize(v1.size()); for_each(v1.begin(), v1.end(), print2); cout << endl; for_each(v2.begin(), v2.end(), print2); cout << endl; for_each(v3.begin(), v3.end(), print2); cout << endl; transform(v1.begin(), v1.end(), v2.begin(),v3.begin(), myplus()); // 匿名函数对象 cout << "--------------" << endl; for_each(v1.begin(), v1.end(), print2); cout << endl; for_each(v2.begin(), v2.end(), print2); cout << endl; for_each(v3.begin(), v3.end(), print2); cout << endl; } 二元谓词: class mycompare04 { public: bool operator()(int v1,int v2) { return v1 > v2; // 从大到小排序 } }; // 二元谓词 应用举例: sort void test04() { vector v.push_back(5); v.push_back(2); v.push_back(7); v.push_back(9); /* template class _Pr> inline void sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred) { // order [_First, _Last), using _Pred _Adl_verify_range(_First, _Last); const auto _UFirst = _Get_unwrapped(_First); const auto _ULast = _Get_unwrapped(_Last); _Sort_unchecked(_UFirst, _ULast, _ULast - _UFirst, _Pass_fn(_Pred)); } */ sort(v.begin(), v.end(),mycompare04()); for (vector { cout << *it << endl; } } 02 stack容器课堂练习 03 queue容器课堂练习 04list容器概念 STL中的list是双向链表 一个节点有两个指针 05 list容器基本操作 mylist.sort(); // 默认从小到大 传入函数对象或者函数指针让他从大到小 对于对象的排序要指定排序方法。 示例: 06 set集合概念 二叉树: 一个节点 每个节点最多有两个子节点 二叉搜索树: 左子树都比父节点小 右子树都比父节点大 这个就叫二叉搜索树 有可能出现左边深度很高 右边深度没那么高的清空 平衡二叉搜索树(平衡二叉树)(尽量保证左子树和右子树深度一样): 红黑树是平衡二叉树的一种 也是达到上面的效果 set容器: 内部是树,自动形成平衡二叉搜索树的机制, 以平衡二叉树(红黑树)为底层实现机制 set容器元素唯一 multiset可以插入重复元素 07 set初始化_插入和删除_find查找 功能:函数lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置. 注意:如果所有元素都小于val,则返回last的位置,且last的位置是越界的!! 功能:函数upper_bound()返回的在前闭后开区间查找的关键字的上界,返回大于val的第一个元素位置 注意:返回查找元素的最后一个可安插位置,也就是“元素值>查找值”的第一个元素的位置。同样,如果val大于数组中全部元素,返回的是last。(注意:数组下标越界) equal_range返回的是一个pair pair.first 是lower_bound pair.second 是 upper_bound 从大到小排序: 方法一: 方法二: 其实内部就是等价于这个: 实现对特定类的排序: multiset: 08 上午课程回顾 栈和队列没提供迭代器 因为内部有自己的实现规则 09 对组 10 map集合概念和四种插入方式区别 #define _CRT_SECURE_NO_WARNINGS #include #include #include using namespace std; // map容器初始化 void test01() { // map容器的模板参数 需要制定key类型 value类型 map map } // map插入操作 void test02() { map // 第一种插入方式 //pair //mymap.insert(mypair); mymap.insert(pair // 第二种 pair<map if (ret.second) { cout << "插入成功" << endl; } else { cout << "插入失败" << endl; } // 第三种 mymap.insert(map // 第四种 mymap[4] = 20; mymap[2] = 100; // 如果key存在,会修改容器指定key元素的值 // 如果你访问的key不存在,他会帮你把这个数据插入进去 pair<map if (ret2.second) { cout << "插入成功" << endl; } else { cout << "插入失败" << endl; } for (map { cout << "key:" << it->first << " value:" << it->second << endl; } cout << endl; } int main(void) { test02(); return 0; } 12 multimap课堂案例 /* 公司今天照片了5个员工 5个员工进入公司之后 需要指派员工在哪个部门工作 人员信息有:姓名 年龄 电话 工资等组成 通过Multimap进行信息的插入 保存 显示 分部门显示员工信息 显示全部员工信息 */ #include #include #include using namespace std; /* 公司今天入职了5个员工 5个员工进入公司之后需要指派员工在哪个部门工作 人员信息有:姓名年龄电话工资等组成 通过multimap进行信息的插入保存显示 分部门显示员工信息显示全部员工信息 */ #define SALE_DEPARTMENT 1 // 销售部 #define DEVELOP_DEPARTMENT 2 // 开发部 #define FINACIAL_DEPARTMENT 3 // 财务部 class Yuangong { public: string name; int age; string tele; double salary; }; // 创建员工 5名 // 返回值 void void Create_Yuangong( vector { // 名字的随机数种子 string nameseed = "ABCDE"; for(int i = 0;i<5;i++) { // 循环创建员工 Yuangong yg; yg.name = "员工"; // 名字加随机数种子 yg.name += nameseed[i]; // 年龄是随机数 yg.name = rand() %30; // 薪水是随机数 yg.salary = rand() %10000 + 10000; // 手机号是固定的 yg.tele = "+86-88888888"; // 把这名员工放到vector中 v.push_back(yg); } } // 给员工指派部门 // 入参:存放员工的vector容器, multimap void Set_YG_Group(vector for(vector cout << "当前员工信息:" << endl; cout << "名字:" << it->name << "年龄: " << it->age << "工资:" < int departmentID = -1; while(true){ cout << "请输入部门(1 销售部 2 开发部 3 财务部) : " << endl; scanf("%d",& departmentID); if(departmentID == SALE_DEPARTMENT){ group.insert(make_pair(SALE_DEPARTMENT,*it)); break; } else if(departmentID == DEVELOP_DEPARTMENT) { group.insert(make_pair(DEVELOP_DEPARTMENT,*it)); break; } else if(departmentID == FINACIAL_DEPARTMENT) { group.insert(make_pair(FINACIAL_DEPARTMENT,*it)); break; } else{ cout << "输入错误,请重新输入:" << endl; } } } } // 打印各部门员工信息 void show_YG_Info(multimap int departmentID = -1; while(true){ cout << "请输入要查看的部门(1 销售部 2 开发部 3 财务部) : " << endl; scanf("%d", &departmentID); // 验证输入有效性 if (departmentID < 1 || departmentID > 3){ continue; } multimap int ygcount = group.count(departmentID); int num =0; while( pos != group.end() && num < ygcount){ cout << "姓名: " << pos->second.name << " 年龄:" << pos->second.age << " 工资:" << pos->second.salary << " 电话:" << pos->second.tele << endl; num++; pos++; } } } int main(void) { vector multimap Create_Yuangong(v); // 3.创建员工并存到容器v中 Set_YG_Group(v,Ygroup); // 4.员工分组 show_YG_Info(Ygroup); // 5.按分组显示员工信息 return 0; } 13 容器元素深拷贝和浅拷贝问题 14 容器的共性机制 1 size() 返回容器中元素的个数 2 empty() 判断容器是否为空 15函数对象课堂基本练习 容器是值语义的 拷贝是值拷贝,push_back的时候是直接把值给原封不动拷贝了一份 执行的是原对象的拷贝构造函数 报错代码: 原因:test01执行完毕的时候执行了两次析构 释放了相同的内存区域 导致报错 解决办法: 重载拷贝构造函数: (这里把等号操作符也重载了 因为声明变量的时候使用=调用的也是拷贝构造函数 16 stl预定义函数对象 (减法:minus) (谓词) #define _CRT_SECURE_NO_WARNINGS #include #include #include #include #include using namespace std; /* template template template template template template */ void test01() { plus int ret = myplus(10, 20); cout << ret << endl; plus<string> myplus2; string s1 = "aaa"; string s2 = "bbb"; string ret2 = myplus2(s2, s1); cout << ret2 << endl; cout << plus } // transform void print(int v) { cout << v << " "; } void test02() { vector for (int i = 0; i < 10;i++) { v1.push_back(i); v2.push_back(i + 1); } v3.resize(v1.size()); // for_each(v3.begin(), v3.end(), print); cout << endl; cout << " -------------- " << endl; transform(v1.begin(), v1.end(), v2.begin(), v3.begin(), plus for_each(v3.begin(), v3.end(), print); cout << endl; } int main(void) { test02(); return 0; }