diff --git a/day9/readme.md b/day9/readme.md
new file mode 100644
index 0000000..5d53ece
--- /dev/null
+++ b/day9/readme.md
@@ -0,0 +1,468 @@
+# STL(一)
+
+### 1. string 容器
+
+> string 也是字符串的类型,可以理解时它是用于存放字符的容器。
+
+#### 1.1 String 和 c 风格字符串对比
+
+```
+1) char * 是一个指针,string 是一个类
+2) string 封装了很多实用的成员方法
+ 查找 find,拷贝 copy,删除 delete 替换 replace,插入 insert
+3) 不用考虑内存释放和越界
+ string 管理 char*所分配的内存。每一次 string 的复制,取值都由 string 类负责维
+护,不用担心复制越界和取值越界等。
+```
+
+#### 1.2 string 容器 api
+
+```
+// 构造函数
+string(); //创建一个空的字符串 例如: string str;
+string(const string& str);//使用一个 string 对象初始化另一个 string 对象
+string(const char* s);//使用字符串 s 初始化
+string(int n, char c); //使用 n 个字符 c 初始化
+
+// 赋值
+string& operator=(const char* s);//char*类型字符串 赋值给当前的字符串
+string& operator=(const string &s);//把字符串 s 赋给当前的字符串
+string& operator=(char c);//字符赋值给当前的字符串
+string& assign(const char *s);//把字符串 s 赋给当前的字符串
+string& assign(const char *s, int n); //把字符串 s 的前 n 个字符赋给当前的字
+符串
+string& assign(const string &s);//把字符串 s 赋给当前字符串
+string& assign(int n, char c);//用 n 个字符 c 赋给当前字符串
+string& assign(const string &s, int start, int n);//将 s 从 start 开始 n 个
+字符赋值给字符串
+
+// 取值
+char& operator[](int n);//通过[]方式取字符
+char& at(int n);//通过 at 方法获取字符
+
+
+// 字符串拼接
+string& operator+=(const string& str);//重载+=操作符
+string& operator+=(const char* str);//重载+=操作符
+string& operator+=(const char c);//重载+=操作符
+string& append(const char *s);//把字符串 s 连接到当前字符串结尾
+string& append(const char *s, int n);//把字符串 s 的前 n 个字符连接到当前字符串结尾
+string& append(const string &s); //同 operator+=()
+string& append(const string &s, int pos, int n);//把字符串 s 中从 pos 的 n 个字符连接到当前字符串结尾
+string& append(int n, char c);//在当前字符串结尾添加 n 个字符 c
+
+// 查找与替换
+int find(const string& str, int pos = 0) const; //查找 str 第一次出现位置, 从 pos 开始查找, 如果未查找到返回 -1
+int find(const char* s, int pos = 0) const; //查找 s 第一次出现位置,从 pos 开始查找
+int find(const char* s, int pos, int n) const; //从 pos 位置查找 s 的前 n个字符第一次位置
+int find(const char c, int pos = 0) const; //查找字符 c 第一次出现位置
+int rfind(const string& str, int pos = npos) const;//查找 str 最后一次位置,从 pos 开始查找
+int rfind(const char* s, int pos = npos) const;//查找 s 最后一次出现位置, 从 pos 开始查找
+int rfind(const char* s, int pos, int n) const;//从 pos 查找 s 的前 n 个字符最后一次位置
+int rfind(const char c, int pos = 0) const; //查找字符 c 最后一次出现位置
+string& replace(int pos, int n, const string& str); //替换从 pos 开始 n 个字符为字符串 str
+string& replace(int pos, int n, const char* s); //替换从 pos 开始的 n 个字符为字符串 s
+
+// 比较 ,返回值 0:相等, 1:大于s, -1:小于s
+int compare(const string &s) const;//与字符串 s 比较
+int compare(const char *s) const;//与字符串 s
+
+// 截取子字符串
+string substr(int pos = 0, int n = npos) const;//返回由 pos 开始的 n 个字符组成的字符串
+
+// 插入与删除
+string& insert(int pos, const char* s); //插入字符串
+string& insert(int pos, const string& str); //插入字符串
+string& insert(int pos, int n, char c);//在指定位置插入 n 个字符 c
+string& erase(int pos, int n = npos);//删除从pos 开始的 n 个
+
+// 转成 char *
+const char * c_str() 将当前字符串转成 char *
+
+// 获取字符串的长度
+int size();
+```
+
+### 2. vector 容器
+
+#### 2.1 vector 与数组的区别
+
+vector 的结构类同于数组,数组是静态的,在定义时确定的数组的大小;而 vector 是动态的,添加元素时如果空间不足时,则会自动扩容器(2^n);整体来说,vector 比较灵活的,而且 vector 是类模板,可以存放任意类型的元素。
+
+#### 2.2 vector 迭代器
+
+> vector 维护一个线性空间(线性连续空间), vector 迭代器所需要的操作行为 是(\*,->, ++, --, +, -, +=, -=)运算符重载等。vector 支持随机存取,vector 提供的是随机访问迭代器(Random Access Iterator), 迭代器中的元素即为 vector 容器中的元素。
+
+【重要说明】: vector 容器扩容之后,原迭代器则无效,需要重新获取获取器
+
+```
+所谓动态增加大小,并不是在原空间之后续接新空间(因为无法保证原空间之后尚有可配置的空间),而是一块更大的内存空间,然后将原数据拷贝新空间,并释放原空间。
+因此,对 vector 的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就都失效了。这是程序员容易犯的一个错误,务必小心。
+```
+
+#### 2.3 vector 容器 api
+
+##### 3.3.1 构造函数
+
+```
+// 构造函数
+vector v; //采用模板实现类实现,默认构造函数
+vector(v.begin(), v.end());//将 v[begin(), end())区间中的元素拷贝给本身。
+vector(n, elem);//构造函数将 n 个 elem 拷贝给本身。
+vector(const vector &vec);//拷贝构造函
+```
+
+##### 3.3.2 赋值操作
+
+```c++
+assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
+assign(n, elem);//将 n 个 elem 拷贝赋值给本身。
+vector& operator=(const vector &vec);//重载等号操作符
+swap(vec);// 将 vec 与本身的元素互换
+```
+
+##### 3.3.3 大小操作
+
+```c++
+int size(); // 返回容器中元素的个数
+bool empty(); //判断容器是否为空, 返回bool值(0, 1)
+void resize(int num); //重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
+void resize(int num, elem); //重新指定容器的长度为 num,若容器变长,则以 elem 值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
+int capacity(); //容器的容量
+void reserve(int len); //容器预留 len 个元素长度,预留位置不初始化,元素不可访问。
+```
+
+##### 3.3.4 存取操作
+
+```c++
+at(int idx); //返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range 异常。
+operator[](int idx); //返回索引 idx 所指的数据,越界时,运行直接报错
+front(); //返回容器中第一个数据元素
+back(); //返回容器中最后一个数据元素
+```
+
+##### 3.3.5 插入和删除
+
+```c++
+insert(const_iterator pos, int count, T ele); //迭代器指向位置 pos 插入 count个元素 ele.
+push_back(ele); //尾部插入元素 ele
+pop_back();//删除最后一个元素
+erase(const_iterator start, const_iterator end); //删除迭代器从 start 到 end 之间的元素, 删除[start, end)区间的所有元素
+erase(const_iterator pos); //删除迭代器指向的元素
+clear(); //删除容器中所有元素
+```
+
+#### 2.4 小技巧示例
+
+##### 2.2.4.1 巧用 swap 收缩内存空间
+
+> resize()+swap()实现 vector 收缩内存空间
+
+```c++
+resize(n);
+vector(v).swap(v);
+```
+
+### 3. deque 容器
+
+#### 3.1 deque 基本概念
+
+vector 容器是单向开口的连续内存空间,deque 则是一种双向开口的连续线性空间。
+
+所谓的双向开口,意思是可以在头尾两端分别做元素的插入和删除操作,当然,vector 容器也可以在头尾两端插入元素,但是在其头部操作效率奇差,无法被接受。
+
+qeque 容器和 vector 容器最大的差异:
+
+```
+1) 在于 deque 允许使用常数项时间对头端进行元素的插入和删除操作。
+2) 在于 deque 没有容量的概念,因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。
+3) deque 没有必须要提供所谓的空间保留(reserve)功能
+4) 虽然deque容器也提供了 Random Access Iterator,但是它的迭代器并不是普通的指针,其复杂度和vector 不是一个量级,这当然影响各个运算的层面。因此,除非有必要,我们应该尽可能的使用vector,而不是deque。
+5)对 deque 进行的排序操作,为了最高效率,可将 deque 先完整的复制到一个 vector 中,对 vector 容器进行排序,再复制回 deque。
+```
+
+#### 3.2 deque 实现原理
+
+逻辑上,deque 容器是连续的空间, 是由一段一段的定量的连续空间构成。一旦有必要在 deque 前端或者尾端增加新的空间,便配置一段连续定量的空间,串接在 deque 的头端或者尾端。
+
+deque 最大的工作就是维护这些分段连续的内存空间的整体性的假象,并提供随机存取的接口。
+
+既然 deque 是分段连续内存空间,那么就必须有中央控制(map 实现的),维持整体连续的假象,数据结构的设计及迭代器的前进后退操作颇为繁琐。
+
+中央控制: 连续小空间,由 map 实现,存放是地址,地址指向的另一个连续空间为缓冲区。
+
+缓冲区:是 deque 的存储空间的主体。
+
+#### 3.3 常用 API
+
+##### 3.3.1 构造函数
+
+```c++
+deque deqT;//默认构造形式
+deque(beg, end);//构造函数将[beg, end)区间中的元素拷贝给本身。
+deque(n, elem);//构造函数将 n 个 elem 拷贝给本身。
+deque(const deque &deq);//拷贝构造函数。
+```
+
+##### 3.3.2 赋值操作
+
+```c++
+assign(beg, end);//将[beg, end)区间中的数据拷贝赋值给本身。
+assign(n, elem);//将 n 个 elem 拷贝赋值给本身。
+deque& operator=(const deque &deq); //重载等号运算符
+swap(deq);// 将 deq 与本身的元素互换
+```
+
+##### 3.3.3 大小操作
+
+```c++
+deque.size();//返回容器中元素的个数
+deque.empty();//判断容器是否为空
+deque.resize(num);//重新指定容器的长度为 num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
+deque.resize(num, elem); //重新指定容器的长度为 num,若容器变长,则以 elem 值填充新位置,如果容器变短,则末尾超出容器长度的元素被删除。
+```
+
+##### 3.3.4 双端插入和删除
+
+```c++
+void push_back(elem);//在容器尾部添加一个数据
+void push_front(elem);//在容器头部插入一个数据
+void pop_back();//删除容器最后一个数据
+void pop_front();//删除容器第一个数据
+```
+
+##### 3.3.5 数据存取
+
+```c++
+at(idx);//返回索引 idx 所指的数据,如果 idx 越界,抛出 out_of_range。
+operator[]; //返回索引 idx 所指的数据,如果 idx 越界,不抛出异常,会直接出错。
+front();//返回第一个数据。
+back();//返回最后一个
+```
+
+如:operator[] 操作数据,超出范围之后,则会直接报错并不抛出异常
+
+> 【注意】 string 泛型的 deque 默认分配 16 个, int 默认 128 个
+
+##### 3.3.6 插入操作
+
+```c++
+void insert(iterator pos,T elem);//在 pos 位置插入一个 elem 元素的拷贝,返回新数据的位置。
+void insert(iterator pos,int n,T elem);//在 pos 位置插入 n 个 elem 数据,无返回值。
+void insert(iterator pos,iter_beg,iter_end);//在 pos 位置插入[beg,end)区间的数据,无返回值。
+```
+
+##### 3.3.7 删除操作
+
+```c++
+clear();//移除容器的所有数据
+iterator erase(iterator beg,iterator end);//删除[beg,end)区间的数据,返回下一个数据的位置。
+iterator erase(iterator pos);//删除 pos 位置的数据,返回下一个数据的位置。
+```
+
+### 4 stack 容器
+
+#### 4.1 stack 基本概念
+
+stack 是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口,stack 容器允许新增元素、移除元素、取得栈顶元素,但是除了最顶端外,没有任何其他方法可以存取 stack 的其他元素。换言之,stack 不允许有遍历行为。
+
+
+
+#### 4.2 stack 没有迭代器
+
+stack 所有元素的进出都必须符合”先进后出”的条件,只有 stack 顶端的元素,才有机会被外界取用。Stack 不提供遍历功能,也不提供迭代器。
+
+#### 4.3 常用 API
+
+##### 4.3.1 构造函数
+
+```
+stack stkT;//stack 采用模板类实现, stack 对象的默认构造形式:
+stack(const stack &stk);//拷贝构造函数
+```
+
+##### 4.3.2 赋值操作
+
+```
+stack& operator=(const stack &stk);//重载等号操作符
+```
+
+##### 4.3.3 数据存取
+
+```c++
+void push(elem);//向栈顶添加元素
+void pop();//从栈顶移除第一个元素
+T top();//返回栈顶元素
+```
+
+##### 4.3.4 大小操作
+
+```
+empty();//判断堆栈是否为空
+size();//返回堆栈的大小
+```
+
+####
+
+案例: 人员的淘汰方式(业绩从高到低、后入职)
+
+```c++
+#include
+#include
+#include
+
+using namespace std;
+class Worker;
+class Date
+{
+ friend Worker;
+ friend ostream &operator<<(ostream &cout, Date &date)
+ {
+ cout << date.year << "年" << date.month << "月" << date.day << "日";
+ return cout;
+ }
+
+private:
+ int year;
+ int month;
+ int day;
+
+public:
+ Date(int year, int month, int day)
+ {
+ this->year = year;
+ this->month = month;
+ this->day = day;
+ }
+ bool operator>(Date &other)
+ {
+ // cout << *this << " pk " << other << endl;
+ return year > other.year || (year == other.year && month > other.month) || (year == other.year && month == other.month && day > other.day);
+ }
+ bool operator<=(Date &other)
+ {
+ return year <= other.year && month <= other.month && day <= other.day;
+ }
+};
+class Worker
+{
+public:
+ string name; // 姓名
+ Date *hire_date; // 入职时间
+ double volume; // 业绩值
+
+public:
+ Worker(const string &name, Date *hire_date, double volume)
+ {
+ this->name = name;
+ this->hire_date = hire_date;
+ this->volume = volume;
+ }
+ Worker(const Worker &other)
+ {
+ Date *hire_date = new Date(other.hire_date->year, other.hire_date->month, other.hire_date->day);
+ this->hire_date = hire_date;
+ this->name = other.name;
+ this->volume = other.volume;
+ }
+ Worker &operator=(const Worker &other)
+ {
+ this->hire_date->year = other.hire_date->year;
+ this->hire_date->month = other.hire_date->month;
+ this->hire_date->day = other.hire_date->day;
+ this->name = other.name;
+ this->volume = other.volume;
+ return *this;
+ }
+
+ ~Worker()
+ {
+ if (hire_date)
+ delete hire_date;
+ hire_date = NULL;
+ }
+
+ void show()
+ {
+ cout << "name=" << name << ",hire_date=" << *hire_date << ",volume=" << volume << endl;
+ }
+};
+
+void sortByHireDate(Worker *p, int size)
+{
+ for (int i = 0; i < size - 1; i++)
+ {
+ int min = i;
+ for (int j = i + 1; j < size; j++)
+ {
+ if (*(p[min].hire_date) > *(p[j].hire_date))
+ {
+ min = j;
+ }
+ }
+ if (min != i)
+ {
+ // cout << p[i].name << " 和 " << p[min].name << " 交换数据" << endl;
+ Worker tmp = p[i]; // 拷贝构造函数
+ p[i] = p[min]; // operator=重载
+ p[min] = tmp;
+ }
+ }
+}
+
+void sortByVolume(Worker *p, int size)
+{
+ for (int i = 0; i < size - 1; i++)
+ {
+ int min = i;
+ for (int j = i + 1; j < size; j++)
+ {
+ if (p[min].volume < p[j].volume)
+ {
+ min = j;
+ }
+ }
+ if (min != i)
+ {
+ // cout << p[i].name << " 和 " << p[min].name << " 交换数据" << endl;
+ Worker tmp = p[i]; // 拷贝构造函数
+ p[i] = p[min]; // operator=重载
+ p[min] = tmp;
+ }
+ }
+}
+
+int main(int argc, char const *argv[])
+{
+ Worker w1("disen", new Date(2020, 1, 15), 1000);
+ Worker w2("jack", new Date(2021, 1, 15), 100);
+ Worker w3("lucy", new Date(2020, 2, 15), 500);
+ Worker w4("mack", new Date(2020, 3, 25), 300);
+ Worker w5("judy", new Date(2022, 5, 18), 400);
+ Worker w6("rose", new Date(2023, 1, 10), 1200);
+
+ Worker m[] = {w1, w2, w3, w4, w5, w6};
+ // sortByHireDate(m, 6);
+ sortByVolume(m, 6);
+ vector v1(m, m + 6);
+ stack s1;
+ vector::iterator it = v1.begin();
+ while (it != v1.end())
+ {
+ (*it).show();
+ s1.push(*it);
+ it++;
+ }
+
+ // 辞退2位新来的员工
+ // cout << "-----辞退2位新来的员工----" << endl;
+ cout << "-----业绩最差的2位员工----" << endl;
+ for (int i = 0; i < 2; i++)
+ {
+ s1.top().show();
+ s1.pop();
+ }
+
+ return 0;
+}
+```
diff --git a/day9/stl_deque_demo/d1.cpp b/day9/stl_deque_demo/d1.cpp
new file mode 100644
index 0000000..b2a992d
--- /dev/null
+++ b/day9/stl_deque_demo/d1.cpp
@@ -0,0 +1,53 @@
+// deque 的使用
+// deque 是一个双端队列,可以在队列的头部和尾部进行插入和删除操作
+
+// deque 的常用操作
+// push_back() 在队列尾部插入元素
+// push_front() 在队列头部插入元素
+// front() 访问队列头部元素
+// back() 访问队列尾部元素
+// pop_front() 删除队列头部元素
+// pop_back() 删除队列尾部元素
+// size() 队列的大小
+// empty() 队列是否为空
+// clear() 清空队列
+// erase() 删除指定位置的元素
+// insert() 在指定位置插入元素
+// operator[] 访问指定位置的元素
+// at() 访问指定位置的元素
+// begin() 返回指向队列头部的迭代器
+// end() 返回指向队列尾部的迭代器
+// rbegin() 返回指向队列尾部的逆向迭代器
+// rend() 返回指向队列头部的逆向迭代器
+// swap() 交换两个队列
+// emplace() 在指定位置构造元素
+// emplace_front() 在队列头部构造元素
+// emplace_back() 在队列尾部构造元素
+// resize() 改变队列的大小
+// assign() 赋值
+// get_allocator() 返回队列的配置器
+// max_size() 返回队列最大可以存储的元素数量
+// shrink_to_fit() 将内存减少到等于当前元素数量所需的大小
+// cbegin() 返回指向队列头部的常量迭代器
+// cend() 返回指向队列尾部的常量迭代器
+
+#include
+#include
+
+int main()
+{
+ std::deque dq;
+
+ dq.push_back(1); // 在队列尾部插入元素
+ dq.push_front(2); // 在队列头部插入元素
+
+ std::cout << "Front: " << dq.front() << std::endl; // 访问队列头部元素
+ std::cout << "Back: " << dq.back() << std::endl; // 访问队列尾部元素
+
+ dq.pop_front(); // 删除队列头部元素
+ dq.pop_back(); // 删除队列尾部元素
+
+ std::cout << "Size: " << dq.size() << std::endl; // 队列的大小
+
+ return 0;
+}
diff --git a/day9/stl_deque_demo/d2.cpp b/day9/stl_deque_demo/d2.cpp
new file mode 100644
index 0000000..7480d1c
--- /dev/null
+++ b/day9/stl_deque_demo/d2.cpp
@@ -0,0 +1,20 @@
+#include
+
+using namespace std;
+
+int main()
+{
+ int m[] = {1, 2, 3, 4, 5, 6};
+ deque d1;
+ deque d2(m, m + 6);
+
+ deque::iterator it = d2.begin();
+ while (it != d2.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+
+ return 0;
+}
diff --git a/day9/stl_deque_demo/d3.cpp b/day9/stl_deque_demo/d3.cpp
new file mode 100644
index 0000000..4c7b530
--- /dev/null
+++ b/day9/stl_deque_demo/d3.cpp
@@ -0,0 +1,41 @@
+#include
+
+using namespace std;
+
+template
+void print(deque &dq)
+{
+ typename deque::iterator it = dq.begin();
+ while (it != dq.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int m[] = {1, 2, 3, 4, 5, 6};
+ deque d1;
+ deque d2(m, m + 6);
+
+ deque d4 = d2; // 拷贝构造函数: deque(const deque &deq)
+ print(d4);
+
+ d1 = d2; // 赋值运算符: deque& operator=(const deque &deq)
+ print(d1);
+
+ print(d2);
+
+ deque d3(10, 1); // 10 个 1
+ print(d3);
+
+ cout << "d5.swap(d2):" << endl;
+ deque d5;
+ d5.swap(d2);
+ print(d5);
+ print(d2);
+
+ return 0;
+}
diff --git a/day9/stl_deque_demo/d4.cpp b/day9/stl_deque_demo/d4.cpp
new file mode 100644
index 0000000..ff90156
--- /dev/null
+++ b/day9/stl_deque_demo/d4.cpp
@@ -0,0 +1,43 @@
+#include
+#include
+
+using namespace std;
+
+class Person
+{
+ friend void print(deque &dq);
+
+private:
+ string name;
+ int age;
+
+public:
+ Person(string name, int age) : name(name), age(age) {}
+};
+
+void print(deque &dq)
+{
+ deque::iterator it = dq.begin();
+ while (it != dq.end())
+ {
+ cout << (*it).name << ", " << (*it).age << endl;
+ ;
+ it++;
+ }
+}
+
+int main()
+{
+ deque dq;
+ dq.push_front(Person("张三", 18));
+ dq.push_back(Person("李四", 19));
+ dq.push_front(Person("王五", 20));
+ print(dq);
+
+ cout << "--------" << endl;
+ dq.pop_back();
+ dq.pop_front();
+ print(dq);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/day9/stl_deque_demo/d5.cpp b/day9/stl_deque_demo/d5.cpp
new file mode 100644
index 0000000..ecb53fe
--- /dev/null
+++ b/day9/stl_deque_demo/d5.cpp
@@ -0,0 +1,22 @@
+#include
+#include
+
+using namespace std;
+
+int main()
+{
+ deque d1;
+ // d1.resize(5);
+ cout << "d1.size():" << d1.size() << ", d1.empty():" << d1.empty() << endl;
+
+ try
+ {
+ cout << d1[15] << endl;
+ }
+ catch (...)
+ {
+ cout << "错误" << endl;
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/day9/stl_deque_demo/d6.cpp b/day9/stl_deque_demo/d6.cpp
new file mode 100644
index 0000000..6074f3a
--- /dev/null
+++ b/day9/stl_deque_demo/d6.cpp
@@ -0,0 +1,18 @@
+#include
+
+using namespace std;
+
+int main()
+{
+ deque d1(5, "disen");
+ d1.push_front("jack");
+ d1.push_back("mack");
+ d1.insert(d1.begin() + 1, "lucy");
+ cout << "first element is: " << d1.front() << endl;
+ cout << "last element is: " << d1.back() << endl;
+
+ deque::iterator it = d1.begin();
+ cout << "second element is: " << *(it + 1) << endl;
+
+ return 0;
+}
diff --git a/day9/stl_deque_demo/d7.cpp b/day9/stl_deque_demo/d7.cpp
new file mode 100644
index 0000000..6fa3557
--- /dev/null
+++ b/day9/stl_deque_demo/d7.cpp
@@ -0,0 +1,32 @@
+// deque 的插入操作
+#include
+
+using namespace std;
+
+template
+void print(deque &dq)
+{
+ typename deque::iterator it = dq.begin();
+ while (it != dq.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ deque d1(5, "disen");
+ print(d1);
+
+ d1.insert(d1.begin() + 1, "jack");
+ print(d1);
+
+ string m[] = {"a", "b", "c", "d", "e"};
+ // 将 m 中的 bcd 插入到 d1 中的 第二个 disen 后面
+ d1.insert(d1.begin() + 3, m + 1, m + 4);
+ print(d1);
+
+ return 0;
+}
diff --git a/day9/stl_deque_demo/d8.cpp b/day9/stl_deque_demo/d8.cpp
new file mode 100644
index 0000000..ad14713
--- /dev/null
+++ b/day9/stl_deque_demo/d8.cpp
@@ -0,0 +1,37 @@
+// deque 的删除操作
+#include
+
+using namespace std;
+
+template
+void print(deque &dq)
+{
+ typename deque::iterator it = dq.begin();
+ while (it != dq.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ string m[] = {"a", "b", "c", "d", "e"};
+ deque dq(m, m + 5);
+ print(dq);
+
+ deque::iterator del_it = dq.begin() + 1;
+ // for (int i = 0; i < 3; i++)
+ // {
+ // // dq.erase() 会删除当前元素并返回下一个元素的迭代器
+ // del_it = dq.erase(del_it);
+ // }
+
+ // 第二种删除方式
+ dq.erase(del_it, del_it + 3);
+
+ print(dq);
+
+ return 0;
+}
diff --git a/day9/stl_stack_demo/d1.cpp b/day9/stl_stack_demo/d1.cpp
new file mode 100644
index 0000000..497470c
--- /dev/null
+++ b/day9/stl_stack_demo/d1.cpp
@@ -0,0 +1,53 @@
+// stack 没有迭代器:不支持遍历
+// 原因: 栈是一种特殊的容器,只能在栈顶进行插入和删除操作
+
+// stack 常用接口
+// 1. push(elem); // 入栈
+// 2. pop(); // 出栈
+// 3. top(); // 返回栈顶元素
+// 4. empty(); // 判断栈是否为空
+// 5. size(); // 返回栈中元素的个数
+// 6. swap(stk1, stk2); // 交换两个栈
+
+#include
+#include
+
+using namespace std;
+
+int main()
+{
+ stack stk;
+
+ for (int i = 0; i < 1000; i++)
+ {
+ stk.push(i);
+ }
+
+ cout << "当前栈中元素个数:" << stk.size() << endl;
+ cout << "栈顶的元素: " << stk.top() << endl;
+
+ // 只弹出 600 这个元素
+ // 需要一个临时变量来保存弹出的元素
+ stack tmp_stk;
+ while (stk.top() != 600)
+ {
+ tmp_stk.push(stk.top());
+ stk.pop();
+ }
+ cout << " ----------\n弹出 600 前的栈顶元素: "
+ << stk.top() << endl;
+ stk.pop();
+ cout << "弹出 600 后的栈顶元素: "
+ << stk.top()
+ << endl
+ << " ----------\n";
+ while (!tmp_stk.empty())
+ {
+ stk.push(tmp_stk.top());
+ tmp_stk.pop();
+ }
+ cout << "当前栈中元素个数:" << stk.size() << endl;
+ cout << "栈顶的元素: " << stk.top() << endl;
+
+ return 0;
+}
\ No newline at end of file
diff --git a/day9/stl_stack_demo/d2.cpp b/day9/stl_stack_demo/d2.cpp
new file mode 100644
index 0000000..17fb1a7
--- /dev/null
+++ b/day9/stl_stack_demo/d2.cpp
@@ -0,0 +1,142 @@
+#include
+#include
+#include
+
+using namespace std;
+
+class Date
+{
+ // 重载 << 以显示日期
+ friend ostream &operator<<(ostream &out, const Date &date)
+ {
+ out << date.year << "年" << date.month << "月" << date.day << "日";
+ return out;
+ }
+
+private:
+ int year;
+ int month;
+ int day;
+
+public:
+ Date(int y, int m, int d) : year(y), month(m), day(d) {}
+
+public:
+ bool operator<(const Date &date) const
+ {
+ // if (year < date.year)
+ // {
+ // return true;
+ // }
+ // else if (year == date.year)
+ // {
+ // if (month < date.month)
+ // {
+ // return true;
+ // }
+ // else if (month == date.month)
+ // {
+ // if (day < date.day)
+ // {
+ // return true;
+ // }
+ // }
+ // }
+ // return false;
+ return year < date.year ||
+ (year == date.year && month < date.month) ||
+ (year == date.year && month == date.month && day < date.day);
+ }
+ bool operator>(const Date &date) const
+ {
+ return year > date.year && month > date.month && day > date.day;
+ }
+};
+
+class Worker
+{
+ friend Worker &operator=(const Worker &other);
+ // {
+ // if (this != &other)
+ // {
+ // name = other.name;
+ // hire_date = other.hire_date;
+ // volume = other.volume;
+ // }
+ // return *this;
+ // }
+
+private:
+ string name; // 姓名
+ Date hire_date; // 入职日期
+ double volume; // 业绩
+
+public:
+ Worker(const string &name, const Date &hire_date, double volume)
+ : name(name), hire_date(hire_date), volume(volume) {}
+ Worker(const Worker &other)
+ {
+ name = other.name;
+ hire_date = other.hire_date;
+ volume = other.volume;
+ }
+ ~Worker()
+ {
+ cout << "析构函数被调用" << endl;
+ }
+
+public:
+ void show()
+ {
+ cout << "name = " << name << ", hire_date = " << hire_date << ", volume = " << volume << endl;
+ }
+};
+
+Worker &operator=(const Worker &other)
+{
+ name = other.name;
+ hire_date = other.hire_date;
+ volume = other.volume;
+}
+
+void sortByHireDate(Worker *p, int size)
+{
+ for (int i = 0; i < size - 1; i++)
+ int min = i;
+ for (int j = i + 1; j < size; i++)
+ {
+ if (p[min].hire_date > p[j].hire_date)
+ {
+ min = j;
+ }
+ }
+ if (min != i)
+ {
+ swap(p[min], p[i]);
+ // Worker tmp = p[i]; // 拷贝构造
+ // p[i] = p[min]; // operator= 重载
+ // p[min] = tmp;
+ }
+}
+
+void sortByVolume(Worker *p, int size)
+{
+}
+
+int main()
+{
+ Worker w1("disen", Date(2020, 1, 15), 1000);
+ Worker w2("zhangsan", Date(2020, 1, 16), 200);
+ Worker w3("lisi", Date(2020, 2, 17), 400);
+ Worker w4("wangwu", Date(2020, 2, 18), 900);
+ Worker w5("zhaoliu", Date(2020, 2, 18), 100);
+
+ Worker wrks[] = {w1, w2, w3, w4, w5};
+
+ sortByHireDate(wrks, 5); // 先排序
+
+ // vector vec;
+ // vec.assign(wrks, wrks + 5);
+
+ w1.show();
+}
\ No newline at end of file
diff --git a/day9/stl_stack_demo/d2_2.cpp b/day9/stl_stack_demo/d2_2.cpp
new file mode 100644
index 0000000..ea79b93
--- /dev/null
+++ b/day9/stl_stack_demo/d2_2.cpp
@@ -0,0 +1,158 @@
+#include
+#include
+#include
+
+using namespace std;
+class Worker;
+class Date
+{
+ friend Worker;
+ friend ostream &operator<<(ostream &cout, Date &date)
+ {
+ cout << date.year << "年" << date.month << "月" << date.day << "日";
+ return cout;
+ }
+
+private:
+ int year;
+ int month;
+ int day;
+
+public:
+ Date(int year, int month, int day)
+ {
+ this->year = year;
+ this->month = month;
+ this->day = day;
+ }
+ bool operator>(Date &other)
+ {
+ // cout << *this << " pk " << other << endl;
+ return year > other.year || (year == other.year && month > other.month) || (year == other.year && month == other.month && day > other.day);
+ }
+ bool operator<=(Date &other)
+ {
+ return year <= other.year && month <= other.month && day <= other.day;
+ }
+};
+class Worker
+{
+public:
+ string name; // 姓名
+ Date *hire_date; // 入职时间
+ double volume; // 业绩值
+
+public:
+ Worker(const string &name, Date *hire_date, double volume)
+ {
+ this->name = name;
+ this->hire_date = hire_date;
+ this->volume = volume;
+ }
+ Worker(const Worker &other)
+ {
+ Date *hire_date = new Date(other.hire_date->year, other.hire_date->month, other.hire_date->day);
+ this->hire_date = hire_date;
+ this->name = other.name;
+ this->volume = other.volume;
+ }
+ Worker &operator=(const Worker &other)
+ {
+ this->hire_date->year = other.hire_date->year;
+ this->hire_date->month = other.hire_date->month;
+ this->hire_date->day = other.hire_date->day;
+ this->name = other.name;
+ this->volume = other.volume;
+ return *this;
+ }
+
+ ~Worker()
+ {
+ if (hire_date)
+ delete hire_date;
+ hire_date = NULL;
+ }
+
+ void show()
+ {
+ cout << "name=" << name << ",hire_date=" << *hire_date << ",volume=" << volume << endl;
+ }
+};
+
+void sortByHireDate(Worker *p, int size)
+{
+ for (int i = 0; i < size - 1; i++)
+ {
+ int min = i;
+ for (int j = i + 1; j < size; j++)
+ {
+ if (*(p[min].hire_date) > *(p[j].hire_date))
+ {
+ min = j;
+ }
+ }
+ if (min != i)
+ {
+ // cout << p[i].name << " 和 " << p[min].name << " 交换数据" << endl;
+ Worker tmp = p[i]; // 拷贝构造函数
+ p[i] = p[min]; // operator=重载
+ p[min] = tmp;
+ }
+ }
+}
+
+void sortByVolume(Worker *p, int size)
+{
+ for (int i = 0; i < size - 1; i++)
+ {
+ int min = i;
+ for (int j = i + 1; j < size; j++)
+ {
+ if (p[min].volume < p[j].volume)
+ {
+ min = j;
+ }
+ }
+ if (min != i)
+ {
+ // cout << p[i].name << " 和 " << p[min].name << " 交换数据" << endl;
+ Worker tmp = p[i]; // 拷贝构造函数
+ p[i] = p[min]; // operator=重载
+ p[min] = tmp;
+ }
+ }
+}
+
+int main(int argc, char const *argv[])
+{
+ Worker w1("disen", new Date(2020, 1, 15), 1000);
+ Worker w2("jack", new Date(2021, 1, 15), 100);
+ Worker w3("lucy", new Date(2020, 2, 15), 500);
+ Worker w4("mack", new Date(2020, 3, 25), 300);
+ Worker w5("judy", new Date(2022, 5, 18), 400);
+ Worker w6("rose", new Date(2023, 1, 10), 1200);
+
+ Worker m[] = {w1, w2, w3, w4, w5, w6};
+ // sortByHireDate(m, 6);
+ sortByVolume(m, 6);
+ vector v1(m, m + 6);
+ stack s1;
+ vector::iterator it = v1.begin();
+ while (it != v1.end())
+ {
+ (*it).show();
+ s1.push(*it);
+ it++;
+ }
+
+ // 辞退2位新来的员工
+ // cout << "-----辞退2位新来的员工----" << endl;
+ cout << "-----业绩最差的2位员工----" << endl;
+ for (int i = 0; i < 2; i++)
+ {
+ s1.top().show();
+ s1.pop();
+ }
+
+ return 0;
+}
\ No newline at end of file
diff --git a/day9/stl_string_demo/d1.cpp b/day9/stl_string_demo/d1.cpp
new file mode 100644
index 0000000..fec3bf8
--- /dev/null
+++ b/day9/stl_string_demo/d1.cpp
@@ -0,0 +1,54 @@
+// string 类型的常用方法
+
+// string 与 char* 的区别
+
+#include
+
+using namespace std;
+
+int main()
+{
+ string s1("ism ");
+ string s2("hhhsishg");
+
+ // 拼接
+ // s1 += s2;
+ s1.append(s2);
+
+ /******************
+ // 修改指定位置的内容
+ s1[0] = 'l';
+
+ // 替换
+ // int c_pos = s1.find('h'); // 查找字符 h 的位置
+ // s1.replace(c_pos, 1, "d"); // 替换字符 h 为 d
+
+ // 替换所有的 h 为 d
+ int pos = s1.find('h');
+ cout << "h pos = " << pos << endl;
+ // while (pos != string::npos) // npos 表示查找失败
+ while (pos != -1) // -1 表示查找失败
+ {
+ s1.replace(pos, 1, "d");
+ pos = s1.find("h", pos + 1);
+ }
+ ******************/
+
+ // 查找 is 第一次和最后一次出现的位置
+ int is_start = s1.find("is");
+ int is_end = s1.rfind("is");
+ cout << "is_start = " << is_start << endl;
+ cout << "is_end = " << is_end << endl;
+
+ // 查找 is 的长度
+ string s3("is");
+ cout << "is 的长度: " << s3.size() << endl;
+
+ // 清空内容(保留开始和结束的 is)
+ // s1.replace(is_start, is_end - is_start + 2, "");
+ s1.erase(is_start + 2, is_end - is_start - 2);
+
+ cout << s1 << endl;
+
+ return 0;
+}
diff --git a/day9/stl_string_demo/d2.cpp b/day9/stl_string_demo/d2.cpp
new file mode 100644
index 0000000..b2365c7
--- /dev/null
+++ b/day9/stl_string_demo/d2.cpp
@@ -0,0 +1,28 @@
+#include
+
+using namespace std;
+
+int main()
+{
+ string s1 = "linux c/c++中指针与引用是课程的重点知识";
+ s1.replace(s1.find('/'), 1, "//");
+ cout << s1 << endl;
+
+ s1.erase(2, 5); // 删除从下标为2开始的5个字符
+ s1.insert(2, 5, '*'); // 在下标为2的位置插入5个字符*
+
+ // s1.replace(2, 5, "*****"); // 从下标为2开始的5个字符替换为5个字符*
+ // s1.replace(2, 5, "*****", 2, 3); // 从下标为2开始的5个字符替换为从下标为2开始的3个字符
+
+ cout << s1 << endl;
+
+ string::iterator it = s1.begin();
+ while (it != s1.end())
+ {
+ cout << *it << " "; // 中文字符迭代器无法识别,会输出乱码,因为中文字符 UTF-8 占用3个字节
+ it++;
+ }
+ cout << endl;
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d10.cpp b/day9/stl_vector_demo/d10.cpp
new file mode 100644
index 0000000..f25df5b
--- /dev/null
+++ b/day9/stl_vector_demo/d10.cpp
@@ -0,0 +1,45 @@
+
+// vector 的删除操作
+#include
+
+using namespace std;
+
+template
+void print(vector &v)
+{
+ typename vector::iterator it = v.begin();
+ while (it != v.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+ print(v1);
+
+ vector::iterator it = v1.begin();
+ v1.insert(it, 1, 10); // 在 it 位置插入 1 个 10
+ print(v1);
+
+ it = v1.begin(); // 重新获取迭代器,因为之前的迭代器已经失效(插入后迭代器首地址变了)
+ v1.erase(it); // 删除 it 位置的元素
+ print(v1);
+
+ it = v1.begin();
+ v1.erase(it, it + 2); // 删除 [it, it+2) 位置的元素
+ print(v1);
+
+ // 清空
+ v1.clear();
+ v1.empty(); // 判断是否为空
+ cout << "清空后:" << endl;
+ print(v1);
+ cout << "size: " << v1.size() << " capacity: " << v1.capacity() << endl; // size: 0 capacity: 8
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d11.cpp b/day9/stl_vector_demo/d11.cpp
new file mode 100644
index 0000000..5c4384d
--- /dev/null
+++ b/day9/stl_vector_demo/d11.cpp
@@ -0,0 +1,35 @@
+
+// vector 的删除操作
+#include
+
+using namespace std;
+
+template
+void print(vector &v)
+{
+ typename vector::iterator it = v.begin();
+ while (it != v.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+ print(v1);
+
+ vector::iterator it = v1.begin();
+ v1.insert(it, 1, 10); // 在 it 位置插入 1 个 10
+ print(v1);
+
+ v1.resize(0); // 缩小
+ vector(v1).swap(v1); // 重新分配内存
+ print(v1);
+ cout << "size: " << v1.size() << " capacity: " << v1.capacity() << endl; // size: 2 capacity: 8
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d3.cpp b/day9/stl_vector_demo/d3.cpp
new file mode 100644
index 0000000..5615993
--- /dev/null
+++ b/day9/stl_vector_demo/d3.cpp
@@ -0,0 +1,28 @@
+// vector 的使用
+
+#include
+
+using namespace std;
+
+int main()
+{
+ vector v1;
+ // int mSize = v1.size(); // 获取容器中元素的个数
+ int mCapacity = v1.capacity(); // 获取容器的容量
+ int cnt = 0; // 扩容次数
+ cout << "初始容量: " << mCapacity << endl;
+ for (int i = 0; i < 1000; i++)
+ {
+ v1.push_back(i); // 向容器中添加元素
+ // cout << "size = " << v1.size() << " capacity = " << v1.capacity() << endl;
+ if (mCapacity != v1.capacity())
+ {
+
+ mCapacity = v1.capacity();
+ cout << "第" << ++cnt << "次扩容, "
+ << "当前容量为: " << v1.capacity() << endl;
+ }
+ }
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d4.cpp b/day9/stl_vector_demo/d4.cpp
new file mode 100644
index 0000000..98ab88c
--- /dev/null
+++ b/day9/stl_vector_demo/d4.cpp
@@ -0,0 +1,23 @@
+#include
+
+using namespace std;
+
+int main()
+{
+ int arr[] = {1, 2, 3, 4, 5, 9}; // 静态数组
+ // vector v1(arr, arr + 5); // 动态数组,通过静态数组初始化
+ // vector v1(arr, arr + sizeof(arr) / sizeof(arr[0])); // 动态数组,通过静态数组初始化
+
+ // 使用 assign 方法初始化
+ vector v1;
+ v1.assign(arr, arr + sizeof(arr) / sizeof(arr[0]));
+
+ vector::iterator it = v1.begin(); // 迭代器
+ while (it != v1.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d5.cpp b/day9/stl_vector_demo/d5.cpp
new file mode 100644
index 0000000..3c8513b
--- /dev/null
+++ b/day9/stl_vector_demo/d5.cpp
@@ -0,0 +1,28 @@
+#include
+
+using namespace std;
+
+template
+void print(vector &v)
+{
+ typename vector::iterator it = v.begin();
+ while (it != v.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+ vector v2(5, 1.2f);
+ v1.swap(v2);
+
+ print(v1);
+ print(v2);
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d6.cpp b/day9/stl_vector_demo/d6.cpp
new file mode 100644
index 0000000..8af4a9c
--- /dev/null
+++ b/day9/stl_vector_demo/d6.cpp
@@ -0,0 +1,20 @@
+#include
+
+using namespace std;
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+ cout << "size: " << v1.size() << endl;
+ cout << "capacity: " << v1.capacity() << endl;
+ cout << "first addr: " << &v1[0] << endl;
+
+ v1.resize(20); // 重新指定容器的长度
+ cout << "size: " << v1.size() << endl;
+ cout << "capacity: " << v1.capacity() << endl;
+ // 调整前后首地址会发生变化
+ cout << "first addr: " << &v1[0] << endl;
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d7.cpp b/day9/stl_vector_demo/d7.cpp
new file mode 100644
index 0000000..d582345
--- /dev/null
+++ b/day9/stl_vector_demo/d7.cpp
@@ -0,0 +1,36 @@
+#include
+
+using namespace std;
+
+template
+void print(vector &v)
+{
+ typename vector::iterator it = v.begin();
+ while (it != v.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+
+ v1.resize(10, 9); // 重新指定容器的长度,并用9填充
+ print(v1);
+
+ vector v2;
+ v2.reserve(3); // 预留足够的空间避免频繁扩容导致的首地址变化
+ // v2.resize(2); // resize 也可以预留空间,但是不会填充
+ v2.push_back(1);
+ cout << "first addr: " << &v2[0] << endl;
+ v2.push_back(2);
+ cout << "first addr: " << &v2[0] << endl;
+ v2.push_back(3);
+ cout << "first addr: " << &v2[0] << endl;
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d8.cpp b/day9/stl_vector_demo/d8.cpp
new file mode 100644
index 0000000..6a663dd
--- /dev/null
+++ b/day9/stl_vector_demo/d8.cpp
@@ -0,0 +1,30 @@
+#include
+
+using namespace std;
+
+template
+void print(vector &v)
+{
+ typename vector::iterator it = v.begin();
+ while (it != v.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+
+ print(v1);
+
+ cout << "first element is: " << v1.front() << endl;
+ cout << "first element addr is: " << &v1.front() << endl; // 与 day9/d7.cpp 中的 first addr 不同
+ cout << "last element is: " << v1.back() << endl;
+ cout << "last element addr is: " << &v1.back() << endl; // 与 day9/d7.cpp 中的 first addr 不同
+
+ return 0;
+}
diff --git a/day9/stl_vector_demo/d9.cpp b/day9/stl_vector_demo/d9.cpp
new file mode 100644
index 0000000..7c44b9f
--- /dev/null
+++ b/day9/stl_vector_demo/d9.cpp
@@ -0,0 +1,34 @@
+
+// vector 的插入操作
+#include
+
+using namespace std;
+
+template
+void print(vector &v)
+{
+ typename vector::iterator it = v.begin();
+ while (it != v.end())
+ {
+ cout << *it << " ";
+ it++;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ int arr1[5] = {1, 2, 3, 4, 5};
+ vector v1(arr1, arr1 + 5);
+ print(v1);
+
+ vector::iterator it = v1.begin();
+ v1.insert(it, 1, 10); // 在 it 位置插入 1 个 10
+ print(v1);
+
+ vector::iterator it2 = v1.begin();
+ v1.insert(it2, 2, 9); // 在 it 位置插入 2 个 9,之前的元素会向后移动
+ print(v1);
+
+ return 0;
+}