其他未完成
This commit is contained in:
BIN
Binary file not shown.
|
After Width: | Height: | Size: 166 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 343 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 212 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 120 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 97 KiB |
Executable
+289
@@ -0,0 +1,289 @@
|
||||
## 二、STL容器II
|
||||
|
||||
### 2.1 queue 容器
|
||||
|
||||
#### 2.1.1 queue概念
|
||||
|
||||
> Queue 是一种先进先出(First In First Out,FIFO)的数据结构,它有两个出口,queue
|
||||
> 容器允许从一端新增元素,从另一端移除元素。
|
||||
|
||||

|
||||
|
||||
#### 2.1.2 queue 没有迭代器
|
||||
|
||||
Queue 所有元素的进出都必须符合”先进先出”的条件,只有 queue 的顶端元素,才
|
||||
有机会被外界取用。Queue 不提供遍历功能,也不提供迭代器。
|
||||
|
||||
|
||||
|
||||
#### 2.1.3 常用API
|
||||
|
||||
##### 2.1.3.1 构造函数
|
||||
|
||||
```c++
|
||||
queue<T> queT; //queue 采用模板类实现,queue 对象的默认构造形式:
|
||||
queue(const queue &que);//拷贝构造函数
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.1.3.2 存取、插入和删除
|
||||
|
||||
```c++
|
||||
void push(elem); //往队尾添加元素
|
||||
void pop(); //从队头移除第一个元素
|
||||
T back(); //返回最后一个元素
|
||||
T front(); //返回第一个元素
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.1.3.3 赋值与大小
|
||||
|
||||
```c++
|
||||
queue& operator=(const queue &que);//重载等号操作符
|
||||
|
||||
empty();//判断队列是否为空
|
||||
size();//返回队列的大小
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.2 list 容器
|
||||
|
||||
#### 2.2.1 list 概念
|
||||
|
||||
list(链表)是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
|
||||
|
||||
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
|
||||
|
||||
每个结点包括两个部分:
|
||||
|
||||
```
|
||||
1)存储数据元素的数据域,
|
||||
2)存储下一个结点地址的指针域
|
||||
```
|
||||
|
||||
list与vector的比较:
|
||||
|
||||
```
|
||||
1) 相对于vector 的连续线性空间,list 就显得负责许多,每次插入或者删除一个元素,就是配置或者释放一个元素的空间。不浪费多余的空间,且插入与移除元素的操作是常数时间(稳定)。
|
||||
2)list和vector 是两个最常被使用的容器, 但list是由双向链表实现的。
|
||||
3)list插入操作和删除操作都不会造成原有 list 迭代器的失效。 【重要特性】
|
||||
```
|
||||
|
||||
<img src="./readme.assets/image-20230804075335829.png" width="400">
|
||||
|
||||
list特点:
|
||||
|
||||
```
|
||||
1)采用动态存储分配,不会造成内存浪费和溢出
|
||||
2)链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
|
||||
3)链表灵活,但是空间和时间额外耗费较大
|
||||
```
|
||||
|
||||
#### 2.2.2 list 的迭代器
|
||||
|
||||
List 不能像 vector 一样以普通指针作为迭代器,因为其节点不能保证在同一块连续的内存空间上。。List 迭代器必须有能力指向 list 的节点,并有能力进行正确的递增、递减、取值、成员存取操作。**递增**时指向下一个节点,**递减**时指向上一个节点,**取值**时取的是节点的数据值,**成员取用**时取的是节点的成员。
|
||||
|
||||
另外,list 是一个双向链表,迭代器必须能够具备前移、后移的能力,所以 list 容器提供的是 Bidirectional Iterators.(双向的迭代器)。
|
||||
|
||||
List 有一个重要的性质,插入操作和删除操作都不会造成原有 list 迭代器的失效。
|
||||
|
||||
<font color=red>【注意】list的迭代器,不支持`+n`操作。</font>
|
||||
|
||||
#### 2.2.3 list 数据结构
|
||||
|
||||
> list 容器不仅是一个双向链表,而且还是一个循环的双向链表。
|
||||
|
||||
#### 2.2.4 常用API
|
||||
|
||||
##### 2.2.4.1 构造函数
|
||||
|
||||
```c++
|
||||
list<T> lstT;//list 采用采用模板类实现,对象的默认构造形式:
|
||||
list(beg,end);//构造函数将[beg, end)区间中的元素拷贝给本身。
|
||||
list(n,elem);//构造函数将 n 个 elem 拷贝给本身。
|
||||
list(const list &lst);//拷贝构造函数
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.2.4.2 插入和删除
|
||||
|
||||
```c++
|
||||
push_back(elem);//在容器尾部加入一个元素
|
||||
pop_back();//删除容器中最后一个元素
|
||||
push_front(elem);//在容器开头插入一个元素
|
||||
pop_front();//从容器开头移除第一个元素
|
||||
insert(pos,elem);//在 pos 位置插 elem 元素的拷贝,返回新数据的位置。
|
||||
insert(pos,n,elem);//在 pos 位置插入 n 个 elem 数据,无返回值。
|
||||
insert(pos,beg,end);//在 pos 位置插入[beg,end)区间的数据,无返回值。
|
||||
clear();//移除容器的所有数据
|
||||
|
||||
erase(beg,end);//删除[beg,end)区间的数据,返回下一个数据的位置。
|
||||
erase(pos);//删除 pos 位置的数据,返回下一个数据的位置。
|
||||
remove(elem);//删除容器中所有与 elem 值匹配的元素
|
||||
```
|
||||
|
||||
##### 2.2.4.3 大小
|
||||
|
||||
```c++
|
||||
size();//返回容器中元素的个数
|
||||
empty();//判断容器是否为空
|
||||
resize(num);//重新指定容器的长度为 num, 若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除
|
||||
resize(num, elem);
|
||||
```
|
||||
|
||||
##### 2.2.4.4 赋值
|
||||
|
||||
```c++
|
||||
assign(beg, end); //将[beg, end)区间中的数据拷贝赋值给本身。
|
||||
assign(n, elem); //将 n 个 elem 拷贝赋值给本身。
|
||||
list& operator=(const list &lst); //重载等号操作符
|
||||
swap(lst); //将 lst 与本身的元素互换。
|
||||
```
|
||||
|
||||
##### 2.2.4.5 读取
|
||||
|
||||
```
|
||||
front();//返回第一个元素。
|
||||
back();//返回最后一个元素
|
||||
```
|
||||
|
||||
##### 2.2.4.6 反转和排序
|
||||
|
||||
```
|
||||
reverse(); //反转链表
|
||||
sort(); //list 排序
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.3 set/multiset 容器
|
||||
|
||||
#### 2.3.1 set概念
|
||||
|
||||
set 的特性是所有元素都会根据元素的键值自动被排序。
|
||||
|
||||
set 的元素即是键值又是实值, 不允许两个元素有相同的键值。
|
||||
|
||||
set 的 iterator 是一种 const_iterator, 不允许修改set的键值。
|
||||
|
||||
set 拥有和 list 某些相同的性质,当对容器中的元素进行插入操作或者删除操作的
|
||||
时候,操作之前的迭代器,在操作完成之后依然有效,被删除的那个元素的迭代器必然是一个例外。
|
||||
|
||||
#### 2.3.2 set数据结构
|
||||
|
||||
multiset 特性及用法和 set 完全相同,唯一的差别在于它允许键值重复。set 和multiset 的底层实现是红黑树,红黑树为平衡二叉树的一种。
|
||||
|
||||
二叉树就是任何节点最多只允许有两个字节点。分别是左子结点和右子节点:
|
||||
|
||||
<img src="./readme.assets/image-20230804083406386.png" width="300">
|
||||
|
||||
二叉搜索树,是指二叉树中的节点按照一定的规则进行排序,使得对二叉树中元素访问更加高效:
|
||||
|
||||
<img src="./readme.assets/image-20230804083459911.png" width=400>
|
||||
|
||||
二叉搜索树的放置规则是:
|
||||
|
||||
任何节点的元素值一定大于其左子树中的每一个节点的元素值,并且小于其右子树的值。因此从根节点一直向左走,一直到无路可走,即得到最小值,一直向右走,直至无路可走,可得到最大值。那么在二叉搜索树中找到最大元素和最小元素是非常简单的事情。
|
||||
|
||||
如上图所示:那么当一个二叉搜索树的左子树和右子树不平衡的时候,那么搜索依据上图表示,搜索 9 所花费的时间要比搜索 17 所花费的时间要多,由于我们的输入或者经过我们插入或者删除操作,二叉树失去平衡,造成搜索效率降低。
|
||||
|
||||
<img src="./readme.assets/image-20230804083751044.png" width=400>
|
||||
|
||||
#### 2.3.3 常用API
|
||||
|
||||
##### 2.3.3.1 构造函数
|
||||
|
||||
```c++
|
||||
set<T> st;//set 默认构造函数:
|
||||
mulitset<T> mst; //multiset 默认构造函数:
|
||||
set(const set &st);//拷贝构造函数
|
||||
```
|
||||
|
||||
##### 2.3.3.2 赋值和大小
|
||||
|
||||
```c++
|
||||
set& operator=(const set &st);//重载等号操作符
|
||||
swap(st);//交换两个集合容器
|
||||
|
||||
size();//返回容器中元素的数目
|
||||
empty();//判断容器是否为空
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### 2.3.3.3 插入和删除
|
||||
|
||||
```
|
||||
insert(elem); //在容器中插入元素。
|
||||
clear(); //清除所有元素
|
||||
erase(pos); //删除 pos 迭代器所指的元素,返回下一个元素的迭代器。
|
||||
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
|
||||
erase(elem); //删除容器中值为 elem 的元素。
|
||||
```
|
||||
|
||||
##### 2.3.3.4 查找
|
||||
|
||||
```c++
|
||||
find(key); //查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返
|
||||
回 set.end();
|
||||
count(key);//查找键 key 的元素个数
|
||||
lower_bound(keyElem);//返回第一个 key>=keyElem 元素的迭代器。
|
||||
upper_bound(keyElem);//返回第一个 key>keyElem 元素的迭代器。
|
||||
equal_range(keyElem);//返回容器中 key 与 keyElem 相等的上下限的两个迭代器。
|
||||
```
|
||||
|
||||
##### 2.3.3.5 set 排序规则
|
||||
|
||||
> set自动排序, 但可以改变它的排序规则,默认从小到大。
|
||||
|
||||
自定义排序规则,可以使用struct或class, 声明 `bool operator(v1, v2)`仿函数重载。
|
||||
|
||||
|
||||
|
||||
#### 2.3.4 对组(pair)
|
||||
|
||||
对组(pair)将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可
|
||||
以分别用 pair 的两个公有属性 first 和 second 访问。
|
||||
|
||||
```
|
||||
类模板:template <class T1, class T2> struct pair
|
||||
```
|
||||
|
||||
用法一:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair1(string("name"), 20);
|
||||
cout << pair1.first << endl;
|
||||
cout << pair1.second << endl;
|
||||
```
|
||||
|
||||
用法二:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair2 = make_pair("name", 30);
|
||||
cout << pair2.first << endl;
|
||||
cout << pair2.second << endl;
|
||||
```
|
||||
|
||||
用法三:
|
||||
|
||||
```c++
|
||||
pair<string, int> pair3 = pair2;
|
||||
cout << pair3.first << endl;
|
||||
cout << pair3.second << endl;
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.4 map/multimap 容器
|
||||
|
||||
Map 的特性是所有元素都会根据元素的键值自动排序。
|
||||
|
||||
Map 所有的元素都是pair,同时拥有实值和键值,pair 的第一元素被视为键值,第二元素被视为实值,map 不允许两个元素有相同的键值。
|
||||
|
||||
multimap 和 map 的操作类似,唯一区别 multimap 键值可重复。
|
||||
map 和 multimap 都是以红黑树为底层实现机制。
|
||||
@@ -0,0 +1,33 @@
|
||||
// 函数对象
|
||||
// 仿函数: 一元,二元仿函数
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 一元仿函数
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A(int n) : n(n) {}
|
||||
int n;
|
||||
// 重载 operator() 运算符,只要调用 A 对象的 (int x) ,就会给对象的对应成员对象加一个 x
|
||||
A &operator()(int i)
|
||||
{
|
||||
this->n += i;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
void print(A a, int n) // A a = A(30)
|
||||
{
|
||||
a(n);
|
||||
cout << "a.n = " << a.n << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 打印 a 对象的值加额外的值的结果
|
||||
print(A(20), 3); // A(20) 会创建一个匿名对象
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 谓词
|
||||
// gt 大于, ge 大于等于
|
||||
// lt 小于, le 小于等于
|
||||
// eq 等于, ne 小于等于
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class GTFive // 一元谓词
|
||||
{
|
||||
public:
|
||||
bool operator()(int n)
|
||||
{
|
||||
return n > 5;
|
||||
}
|
||||
};
|
||||
|
||||
class GT // 二元谓词
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n1, const int &n2)
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
};
|
||||
|
||||
void printGTF(GTFive gtf, int *p, int size)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (gtf(p[i]))
|
||||
cout << p[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(int *p, int size, GT gt, int n)
|
||||
{
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
if (gt(p[i], n))
|
||||
cout << p[i] << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int ms[] = {1, 2, 4, 7, 9, 20};
|
||||
cout << "大于 5 的元素" << endl;
|
||||
printGTF(GTFive(), ms, 6);
|
||||
|
||||
cout << "大于 7 的元素" << endl;
|
||||
print(ms, 6, GT(), 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 算术类函数对象
|
||||
// 算术类函数对象
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <typename T>
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, plus<int> pl, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << pl(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, multiplies<int> mul, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << mul(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
// set 会自动过滤重复,并排序
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
print(s.begin(), s.end(), plus<int>(), 1);
|
||||
print(s.begin(), s.end(), multiplies<int>(), 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// template <typename T>
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, plus<int> pl, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << pl(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void print(typename set<int>::const_iterator start,
|
||||
typename set<int>::const_iterator end, multiplies<int> mul, int m)
|
||||
{
|
||||
for (; start != end; start++)
|
||||
{
|
||||
cout << mul(*start, m) << " ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
void show(int n)
|
||||
{
|
||||
cout << n << " ";
|
||||
}
|
||||
|
||||
// 二元仿函数
|
||||
class PrintPlus : public binary_function<int, int, void>
|
||||
{
|
||||
public:
|
||||
void operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
cout << n1 << "+" << n2 << " = " << n1 + n2 << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
// set 会自动过滤重复,并排序
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
// print(s.begin(), s.end(), plus<int>(), 1);
|
||||
// print(s.begin(), s.end(), multiplies<int>(), 3);
|
||||
|
||||
// for_each(s.begin(), s.end(), show);
|
||||
// cout << endl;
|
||||
|
||||
// PrintPlus 测试
|
||||
// for (int i = 0; i < 6; i++)
|
||||
for_each(s.begin(), s.end(), bind1st(PrintPlus(), i));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class PrintGt5Adapter : public binary_function<int, int, void>
|
||||
{
|
||||
public:
|
||||
void operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
if (n1 > n2)
|
||||
cout << n1 << " ";
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 4, 8, 5, 1, 2};
|
||||
set<int> s(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
for_each(s.begin(), s.end(), bind2nd(PrintGt5Adapter(), 2));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// 取反适配器
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
// 自定义一个适配器,只需要容器中元素即可。
|
||||
class GT5 : public unary_function<int, bool>
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n) const
|
||||
{
|
||||
return n > 5;
|
||||
}
|
||||
};
|
||||
|
||||
class GTN : public binary_function<int, int, bool>
|
||||
{
|
||||
public:
|
||||
bool operator()(const int &n1, const int &n2) const
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
// find_if(start, end, _callback) 返回查找到的第一个迭代器的位置
|
||||
vector<int>::iterator ret = find_if(v.begin(), v.end(), not1(bind2nd(greater<int>(), 3)));
|
||||
cout << *ret << endl;
|
||||
|
||||
ret = find_if(v.begin(), v.end(), GT5());
|
||||
cout << *ret << endl;
|
||||
|
||||
ret = find_if(v.begin(), v.end(), bind2nd(GTN(), 3));
|
||||
cout << *ret << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// 函数指针适配
|
||||
// 使用 ptr_fun<>() 适配函数指针
|
||||
// <> 中的第一个参数是函数指针的类型,第二个参数是函数指针的参数类型,第三个参数是函数指针的返回值类型
|
||||
// bind1st() 和 bind2nd() 适配函数对象
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool gtn(int n1, int n2)
|
||||
{
|
||||
return n1 > n2;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
vector<int>::iterator ret = find_if(v.begin(), v.end(), bind2nd(ptr_fun<int, int, bool>(gtn), 3));
|
||||
cout << *ret << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// mem_fn 有两个重载版本:
|
||||
// 用法1:mem_fn(&MyClass::printMessage) 用于将成员函数转换为函数对象
|
||||
// 用法2:mem_fn(&MyClass::printMessage)(&obj, "hello world") 用于调用成员函数
|
||||
// mem_fn 是一个函数模板,它接受一个成员函数指针或成员函数引用,并返回一个函数对象,该对象可以调用相应的成员函数。
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class Stu
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
int age;
|
||||
|
||||
public:
|
||||
Stu(const string &name, int age) : name(name), age(age) {}
|
||||
|
||||
public:
|
||||
void show()
|
||||
{
|
||||
cout << "name is " << name << ", age is " << age << endl;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
vector<Stu> vs;
|
||||
vs.push_back(Stu("disen", 18));
|
||||
vs.push_back(Stu("lucy", 20));
|
||||
vs.push_back(Stu("jack", 15));
|
||||
vs.push_back(Stu("mack", 19));
|
||||
|
||||
// 遍历容器中所有成员,成员函数作为仿函数时,则通过容器成员调用它的仿函数
|
||||
for_each(vs.begin(), vs.end(), mem_fun_ref(&Stu::show));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
||||
using namespace std;
|
||||
using namespace std::placeholders;
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 2, 3, 5, 10};
|
||||
vector<int> v;
|
||||
v.assign(m, m + sizeof(m) / sizeof(m[0]));
|
||||
|
||||
int target = 3;
|
||||
|
||||
// 使用 std::bind 适配 std::equal_to
|
||||
vector<int>::iterator ret = adjacent_find(v.begin(), v.end(), bind(equal_to<int>(), _1, 3));
|
||||
cout << *(++ret) << endl;
|
||||
|
||||
if (ret != v.end())
|
||||
{
|
||||
cout << "Found adjacent elements equal to " << target << "." << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "No adjacent elements equal to " << target << " found." << endl;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
list<int> lst1(6, 5); // 6 个 5
|
||||
print(lst1);
|
||||
|
||||
string s1 = "abcdefg";
|
||||
|
||||
// 将 string 字符串转换为 list
|
||||
list<char> lst2(s1.begin(), s1.end());
|
||||
print(lst2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
|
||||
// 将 string 字符串转换为 list
|
||||
list<char> l(s.begin(), s.end());
|
||||
int size = l.size(); // 获取大小
|
||||
print(l);
|
||||
|
||||
// list 手写逆序
|
||||
list<char>::iterator it = l.begin(); // 迭代器指向第一个元素
|
||||
for (int i = 0; i < size; i++) // 逆序 size 次
|
||||
{
|
||||
it = l.insert(it, l.back()); // 将最后一个元素插入到第一个元素之前
|
||||
it++; // 迭代器指向下一个元素
|
||||
l.pop_back(); // 删除最后一个元素
|
||||
}
|
||||
|
||||
print(l);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
list<char> l(s.begin(), s.end());
|
||||
|
||||
// 删除 cde
|
||||
// list<char>::iterator it = find(l.begin(), l.end(), 'c');
|
||||
// l.erase(it, find(l.begin(), l.end(), 'e'));
|
||||
|
||||
list<char>::iterator it = l.begin(); // 迭代器指向第一个元素
|
||||
for (int i = 0; i < 2; i++) // 迭代器指向第三个元素
|
||||
it++;
|
||||
list<char>::iterator it2 = it; // 迭代器指向第三个元素
|
||||
for (int i = 0; i < 3; i++) // 迭代器指向第六个元素
|
||||
it2++;
|
||||
l.erase(it, it2); // 删除第三个到第五个元素
|
||||
|
||||
print(l); // a b f g
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const list<T> &lst)
|
||||
{
|
||||
for (typename list<T>::const_iterator it = lst.begin(); it != lst.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
string s = "abcdefg";
|
||||
list<char> l(s.begin(), s.end());
|
||||
print(l);
|
||||
l.reverse(); // 逆序
|
||||
print(l);
|
||||
|
||||
int m[] = {6, 4, 2, 0, 8, 6, 4};
|
||||
list<int> l2(m, m + 7);
|
||||
print(l2);
|
||||
l2.sort(); // 排序
|
||||
print(l2);
|
||||
l2.reverse(); // 逆序
|
||||
print(l2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> ms;
|
||||
|
||||
// 1. insert()函数
|
||||
// map 在插入时会自动根据 map 的键来排序
|
||||
ms.insert(pair<int, string>(1, "张三")); // pair<int, string>是map<int, string>::value_type的类型
|
||||
ms.insert(pair<int, string>(4, "李四"));
|
||||
ms.insert(make_pair(3, "王五")); // make_pair()函数可以自动推导出类型
|
||||
ms.insert(map<int, string>::value_type(2, "赵六")); // value_type是map<int, string>的类型
|
||||
ms[5] = "田七"; // 通过下标的方式插入数据
|
||||
|
||||
map<int, string>::iterator it = ms.begin();
|
||||
for (; it != ms.end(); it++)
|
||||
{
|
||||
// cout << "sid = " << it->first << ",name = " << it->second << endl;
|
||||
cout << "sid = " << (*it).first << ",name = " << (*it).second << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
// 使用 map 来解决括号匹配
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string left_c = "{[(";
|
||||
map<char, char> map1;
|
||||
|
||||
bool valid(const char *p)
|
||||
{
|
||||
stack<char> stk;
|
||||
int max_depth = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
const char &cp = *p;
|
||||
|
||||
// if (left_c.find(cp) != string::npos) // 如果当前拿到的是左括号
|
||||
if (left_c.find(cp) != -1) // 如果当前拿到的是左括号
|
||||
{
|
||||
// 入栈
|
||||
stk.push(*p);
|
||||
}
|
||||
else // 如果当前拿到的是右括号
|
||||
{
|
||||
// 弹栈
|
||||
if (stk.empty())
|
||||
return false;
|
||||
|
||||
const char &top = stk.top();
|
||||
if (map1[cp] != top)
|
||||
return false;
|
||||
|
||||
// 当前左右匹配的后续操作
|
||||
// 求最大深度
|
||||
if (max_depth < stk.size())
|
||||
max_depth = stk.size();
|
||||
|
||||
// 弹栈前判断最大深度
|
||||
stk.pop();
|
||||
}
|
||||
p++;
|
||||
}
|
||||
cout << "当前括号栈的最大深度为: " << max_depth << endl;
|
||||
|
||||
return stk.empty();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
map1.insert(make_pair('}', '{'));
|
||||
map1.insert(make_pair(']', '['));
|
||||
map1.insert(make_pair(')', '('));
|
||||
|
||||
cout << valid("{[()]}[[[[[()]]]]]") << endl;
|
||||
cout << valid("{[())}") << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> m;
|
||||
m.insert(make_pair(1, "disen"));
|
||||
m.insert(make_pair(2, "lucy"));
|
||||
cout << m.size() << endl;
|
||||
m.erase(1); // 删除键值为 1 的元素
|
||||
cout << m.size() << endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
map<int, string> m;
|
||||
m.insert(make_pair(1, "disen"));
|
||||
m.insert(make_pair(2, "lucy"));
|
||||
m.insert(make_pair(3, "jack"));
|
||||
|
||||
map<int, string>::const_iterator it = m.find(3);
|
||||
|
||||
if (it == m.end())
|
||||
{
|
||||
cout << "未查找到" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
const pair<int, string> &p = *it;
|
||||
cout << p.first << ", " << p.second << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const set<T> &s)
|
||||
{
|
||||
for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print(const multiset<T> &s)
|
||||
{
|
||||
for (typename multiset<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {1, 2, 3, 2, 3, 4};
|
||||
set<int> s(m, m + 6);
|
||||
print(s); // set 会自动去重,输出 1 2 3 4
|
||||
|
||||
multiset<int> ms(m, m + 6);
|
||||
print(ms); // multiset 不会自动去重,输出 1 2 2 3 3 4
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template <typename T>
|
||||
void print(const set<T> &s)
|
||||
{
|
||||
for (typename set<T>::const_iterator it = s.begin(); it != s.end(); ++it)
|
||||
cout << *it << ' ';
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int m[] = {5, 12, 16, 21, 22, 27, 29, 30};
|
||||
set<int> s(m, m + 8);
|
||||
print(s); // set 键值自动排序,且不重复
|
||||
|
||||
// 查看大于等于 22 值的所有元素
|
||||
cout << "查看大于等于 22 值的所有元素: " << endl;
|
||||
set<int>::iterator it = s.lower_bound(22); // 返回第一个大于等于 22 的元素的迭代器
|
||||
while (it != s.end())
|
||||
{
|
||||
cout << *it << ' ';
|
||||
++it;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
// 查找小于等于 22 值的所有元素
|
||||
cout << "查找小于等于 22 值的所有元素: " << endl;
|
||||
// it = s.upper_bound(22); // 返回第一个大于 22 的元素的迭代器
|
||||
// for (; it != s.begin();)
|
||||
// {
|
||||
// --it;
|
||||
// cout << *it << ' ';
|
||||
// }
|
||||
// cout << endl;
|
||||
|
||||
// 查找小于等于 22 值的所有元素(另一种写法)
|
||||
it = s.lower_bound(22);
|
||||
while (it != s.begin())
|
||||
{
|
||||
--it;
|
||||
cout << *it << ' ';
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 自定义排序
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 自定义规则
|
||||
template <typename T>
|
||||
class MySort
|
||||
{
|
||||
public:
|
||||
bool operator()(const T &a, const T &b)
|
||||
{
|
||||
return a > b; // 从小到大排序
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// 使用 set 时,添加自定义排序规则
|
||||
set<int, MySort<int> > s1;
|
||||
s1.insert(20);
|
||||
s1.insert(30);
|
||||
s1.insert(1);
|
||||
s1.insert(8);
|
||||
|
||||
set<int, MySort<int> >::iterator it = s1.begin(); // <int, MySort<int>> 可以省略
|
||||
while (it != s1.end())
|
||||
{
|
||||
cout << *it << ' ';
|
||||
++it;
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// 自定义排序
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// 自定义规则
|
||||
template <typename T>
|
||||
class MySort
|
||||
{
|
||||
public:
|
||||
bool operator()(const T &a, const T &b)
|
||||
{
|
||||
return a > b; // 从小到大排序
|
||||
}
|
||||
};
|
||||
|
||||
class Student
|
||||
{
|
||||
public:
|
||||
string name;
|
||||
int age;
|
||||
float score;
|
||||
|
||||
public:
|
||||
Student(const string &name, int age, float score)
|
||||
{
|
||||
this->name = name;
|
||||
this->age = age;
|
||||
this->score = score;
|
||||
}
|
||||
};
|
||||
|
||||
class MyStudentByAgeSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const Student &s1, const Student &s2)
|
||||
{
|
||||
return s1.age > s2.age;
|
||||
}
|
||||
};
|
||||
|
||||
class MyStudentByScoreSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const Student &s1, const Student &s2)
|
||||
{
|
||||
return s1.score > s2.score;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
Student[] *stus = new Student[3]{Student("张三", 18, 100), Student("李四", 20, 90), Student("王五", 19, 95)};
|
||||
set<Student, MyStudentByAgeSort> s2;
|
||||
s2............................
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// pair 是一个模板类,有两个模板参数,
|
||||
// 用于存储两个数据,可以分别指定两个数据的类型
|
||||
pair<int, string> p1(1, "张三");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// 对组(pair)
|
||||
// 将一对值组合成一个值,这一对值可以具有不同的数据类型,两个值可
|
||||
// 以分别用 pair 的两个公有属性 first 和 second 访问。
|
||||
|
||||
// 类模板:template<class T1, class T2> class pair
|
||||
|
||||
// 用法一:
|
||||
|
||||
// pair<string, int> pair1(string("name"), 20);
|
||||
// cout << pair1.first << endl;
|
||||
// cout << pair1.second << endl;
|
||||
|
||||
// 用法二:
|
||||
|
||||
// pair<string, int> pair2 = make_pair("name", 30);
|
||||
// cout << pair2.first << endl;
|
||||
// cout << pair2.second << endl;
|
||||
|
||||
// 用法三:
|
||||
|
||||
// pair<string, int> pair3 = pair2; // 拷贝构造函数
|
||||
// cout << pair3.first << endl;
|
||||
// cout << pair3.second << endl;
|
||||
|
||||
// 如:
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
pair<int, string> p1(1, "disen");
|
||||
pair<int, string> p2 = make_pair(2, "lucy");
|
||||
cout << "id = " << p1.first << ", name = " << p1.second << endl;
|
||||
cout << "id = " << p2.first << ", name = " << p2.second << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user