mirror of
https://github.com/Estom/notes.git
synced 2026-05-04 11:41:25 +08:00
容器和模板算法
This commit is contained in:
@@ -60,6 +60,19 @@ for(delaration:expression)
|
||||
statement
|
||||
```
|
||||
|
||||
### for_each循环
|
||||
|
||||
```
|
||||
for_each(iterator begin,iterator end,func);
|
||||
//使用lambda函数完成循环过程中的元素修改和处理
|
||||
vector<int> vec;
|
||||
for_each(vec.begin(),vec.end(),[](int& a){
|
||||
a=a+1;
|
||||
cout<<a<<endl;
|
||||
return;
|
||||
})
|
||||
```
|
||||
|
||||
## 5 跳转语句
|
||||
```
|
||||
break;
|
||||
|
||||
@@ -20,10 +20,14 @@
|
||||
```
|
||||
### pair定义
|
||||
|
||||

|
||||
```
|
||||
pair<string,string> author{'James","joyce"};
|
||||
```
|
||||
<!--  -->
|
||||
|
||||
### pair操作
|
||||
|
||||

|
||||

|
||||
|
||||
## 1.2 tuple
|
||||
|
||||
@@ -20,46 +20,88 @@
|
||||
|
||||

|
||||
|
||||
## 2 所有容器的基础操作
|
||||
### 容器统一的操作
|
||||
## 2 容器通用操作
|
||||
### 2.0 容器统一的操作
|
||||
|
||||

|
||||

|
||||
<!--  -->
|
||||
<!--  -->
|
||||
|
||||
主要包括六类
|
||||
1. 构造函数和初始化(默认初始化、复制初始化、迭代器初始化、列表初始化)
|
||||
2. 赋值与交换(c1=c2,c1={},assign,swap)
|
||||
1. 构造函数(默认初始化、复制初始化、迭代器初始化、列表初始化)
|
||||
2. 赋值交换(c1=c2,c1={},assign,swap)
|
||||
3. 容器大小(size,max_size,empty)
|
||||
4. 插入删除(insert,emplace,erase,clear)
|
||||
5. 关系运算符(六种关系)
|
||||
5. 关系运算(六种关系)
|
||||
6. 迭代器(八个迭代器begin,end,cbegin,cend,rbegin,rend,crbegin,crend)
|
||||
|
||||
### 容器的构造函数和初始化
|
||||
### 2.1 构造函数
|
||||
|
||||

|
||||
* 共5+3=8种容器的初始化方法。
|
||||
|
||||
### 容器的赋值和交换
|
||||
|
||||

|
||||
方法|说明
|
||||
|----|----|
|
||||
container c| 默认初始化。默认构造函数。
|
||||
container c()|值初始化。默认构造函数。
|
||||
container c(c1)| 直接初始化。普通构造函数。
|
||||
container c=c2 | 拷贝初始化。拷贝构造函数。
|
||||
container c{a,b,c,} container c={a,b,c,}|列表地初始化。使用元素类型,初始化元素类型。对于没有初始化的元素,调用值初始化。
|
||||
container c(iterator begin,iterator end)| 迭代器初始化。使用迭代器指向的范围内的元素进行初始化。
|
||||
seq_container seq(n)| 顺序容器特有的初始化。创建包含n个元素的顺序容器,每个元素进行值初始化。
|
||||
seq_container seq(n,t)| 顺序容器特有的初始化。创建包含n个t元素的顺序容器。每个元素都是t的copy。
|
||||
|
||||
|
||||
### 容器大小
|
||||
<!--  -->
|
||||
|
||||
* size():返回容器中元素的数目
|
||||
* empty():当size为0是返回true
|
||||
* maxsize():返回容器所能容纳的最大元素数的值。
|
||||
### 2.2 赋值交换
|
||||
|
||||
### 插入删除
|
||||
* insert()插入对象
|
||||
* emplace()元素初始化插入
|
||||
* erase()删除指定元素
|
||||
* clear()清空
|
||||
### 关系运算符
|
||||
* 总共六个赋值交换函数。其中赋值为copy赋值。而不是引用copy。容器键的元素不会相互影响。
|
||||
|
||||
|
||||
方法|说明
|
||||
|-----|-----|
|
||||
c1=c2 | 将c1中的元素替换为c2的copy。
|
||||
c={a,b,c,} | 将c1中的元素替换为列表中元素的copy
|
||||
swap(c1,c2) | 交换c1,c2容器中所有的元素。
|
||||
c1.swap(c2) | 交换c1,c2容器中的所有元素。
|
||||
seq.assign({a,b,c,})| 将seq中的元素替换为储值列表中的元素。
|
||||
seq.assign(iterator begin,iterator end) | 将seq中的元素替换为迭代器指向的范围内的元素。
|
||||
seq.assign(n,t) | 将seq中的元素替换为n个值为t的元素
|
||||
|
||||
|
||||
<!--  -->
|
||||
|
||||
|
||||
### 2.3 容器大小
|
||||
|
||||
方法|说明
|
||||
|----|---|
|
||||
int size() | 返回容器中元素的数目
|
||||
bool empty()|当size为0是返回true
|
||||
int maxsize()|返回容器所能容纳的最大元素数的值。
|
||||
|
||||
### 2.4 插入删除
|
||||
|
||||
方法 | 说明
|
||||
|---|---|
|
||||
insert()|插入对象
|
||||
emplace()|元素初始化插入
|
||||
erase()|删除指定元素
|
||||
clear()|清空
|
||||
|
||||
### 2.5 关系运算
|
||||
|
||||
* 容器支持相等和不等的运算。== !=
|
||||
* 除了无序关联容器,都支持关系运算(> < >= <=)
|
||||
* 必须是相同各类型的容器,且元素类型相同才能比较。
|
||||
|
||||
### 2.6 迭代器
|
||||
方法|说明
|
||||
|----|---|
|
||||
begin(),end()|一组迭代器。用来从前到后遍历元素。可以修改元素。
|
||||
cbegin(),cend()|一组迭代器。用来从前到后遍历元素。不可以修改元素。
|
||||
rbegin(),rend()|尾后迭代器。用来从后到前遍历元素。可以修改元素。
|
||||
crbegin(),crend()|尾后迭代器。用来从后到前遍历元素。不可以修改元素。
|
||||
|
||||
## 3 容器的容量问题
|
||||
|
||||
### vector的存储
|
||||
|
||||
@@ -8,62 +8,223 @@
|
||||
> * forward_list
|
||||
> * string//专门用于字符串访问的容器
|
||||
> * vector/deque/list拥有容器所有的操作。首尾相关的操作。
|
||||
## 0 顺序容器的基础操作
|
||||
|
||||
### 向顺序容器中添加元素
|
||||
> 参考文献
|
||||
> * [vector/deque/list详解](https://blog.csdn.net/gogokongyin/article/details/51178378)
|
||||
|
||||

|
||||
## 0 顺序容器的通用操作
|
||||
|
||||
* 在尾部添加元素**push_back(),emplace_back()**
|
||||
* 在头部添加元素**push_front(),emplace_front()**
|
||||
* 在中间添加元素insert(),emplace()
|
||||
> * 对迭代器的理解:迭代器就是指向元素的指针。通过指针的移动来访问元素。效率更快。
|
||||
> * C++ 标准库提供了一系列范围相关的方法。例如
|
||||
> * 范围创建constructor{},constructor(beg,end) constructor(n,t)
|
||||
> * 范围替换assign({}),assign(beg,end),assign(n,t)
|
||||
> * 范围插入insert(p,{}),insert(p,beg,end),insert(p,n,t)
|
||||
> * 范围删除erase(beg,end)
|
||||
> * 范围重构resize(n),resize(n,t)
|
||||
|
||||
|
||||
### 在顺序容器中访问元素
|
||||
### 0.1 访问元素
|
||||
|
||||

|
||||
<!--  -->
|
||||
|
||||
* 也可以使用**迭代器**访问元素。
|
||||
* **at**会进行安全检查抛出异常。
|
||||
* **[]下标运算符**不会进行检查。
|
||||
* **back(),front()**
|
||||
|
||||
### 在顺序容器中删除元素
|
||||
|
||||

|
||||
|
||||
* pop_back(),pop_front();
|
||||
* erease(p),erase(b,e);
|
||||
* clear();
|
||||
|
||||
> 操作记忆
|
||||
> * **back、front、push_back、push_front、pop_back、pop_front、emplace_front、emplace_back**。是一组首尾相关的插入操作。
|
||||
> * **insert、at、erase**。是一组随机的操作。
|
||||
方法 | 说明
|
||||
|----|-----|
|
||||
back() | 尾部元素访问。空容器函数行为未定义。触发异常。
|
||||
front() | 首部元素访问。空容器函数未定义。触发异常。
|
||||
c[] | 随机元素访问。索引外函数未定义。触发异常。
|
||||
at(n) | 随机元素访问。索引外抛出out_of_range异常
|
||||
*iterator | 迭代器元素访问。指针元素访问。
|
||||
|
||||
|
||||
### 0.2 添加元素
|
||||
|
||||
<!--  -->
|
||||
|
||||
|
||||
### 改变容器的大小
|
||||
* 总共有6+3=9种插入方法。insert有额外的两种范围插入方法。
|
||||
* 在尾部添加元素**push_back(),emplace_back()**
|
||||
* 在头部添加元素**push_front(),emplace_front()**
|
||||
* 在中间添加元素insert(),emplace()
|
||||
* insert方法提供了范围插入的方法。中间插入一个元素。在给定的一个迭代器之前插入一个值。中间插入多个元素。在给定的迭代器之前插入范围迭代器内的元素。
|
||||
|
||||

|
||||
方法| 说明
|
||||
|-----|-----|
|
||||
void push_back(T t)|容器尾部添加元素。
|
||||
void emplace_back(args) | 使用args初始化化一个元素。添加到容器尾部。
|
||||
void push_front(T t) | 容器头部添加元素。
|
||||
void emplace_front(args) |使用args初始化一个元素。添加到容器头部。
|
||||
iterator emplace(iterator p,args)|在迭代器指向的元素之前。创建一个args初始化的元素。返回指向新元素的迭代器。
|
||||
iterator insert(iterator p,T t) |在迭代器指向的元素之前。创建一个值为t的元素。返回指向新元素的迭代器。
|
||||
iterator insert(iterator p,iterator begin,iterator end)|在给定的迭代器之前。插入范围迭代器内的元素。返回指向第一个新元素迭代器。
|
||||
iterator insert(iterator p,n,t)|在给定的元素之前。插入指定数量的相同元素。返回指向第一个新元素的迭代器。
|
||||
iterator insert(iterator p,{a,b,c,}) |在给定的元素之前,插入元素值列表中的元素。返回指向第一个新元素的迭代器。
|
||||
|
||||
|
||||
### 0.3 删除元素
|
||||
|
||||
<!--  -->
|
||||
|
||||
* **back、front、push_back、push_front、pop_back、pop_front、emplace_front、emplace_back**。是一组首尾相关的插入操作。
|
||||
* **insert、emplace、at、erase**。是一组随机的操作。
|
||||
|
||||
方法| 说明
|
||||
|----|----|
|
||||
void pop_back(void )|删除末尾的元素
|
||||
void pop_front(void)|删除开头的元素。
|
||||
iterator erease(iterator p) |删除迭代器指向的元素。返回被删除元素之后第一个元素的元素的迭代器。
|
||||
iterator erase(b,e)| 删除范围内的元素。返回被删除范围后的第一个元素的迭代器。
|
||||
void clear()|删除c中所有的元素。
|
||||
|
||||
### 0.4 重构容器
|
||||
|
||||
* 并非该表容器内存的大小。而是改变容器范围的大小。
|
||||
|
||||
<!--  -->
|
||||
|
||||
方法 | 说明
|
||||
|----|----|
|
||||
resize(n) | 调整容器大小为n个元素。多出的元素被丢球。新添加的位置进行值初始化。
|
||||
resize(n,t) | 调整容器的大小为n个元素。任何添加的新元素初始化为t。
|
||||
|
||||
## 1 array
|
||||
> 与数组完全一致,只是定义方式不同。
|
||||
> 数组不能copy赋值,但是array可以copy赋值。
|
||||
|
||||
### 定义
|
||||
是静态的连续数组,只有默认初始化。
|
||||
|
||||
### 特殊构造方法
|
||||
* 是静态的连续数组,只有默认初始化。
|
||||
```
|
||||
array<int, 5> arr = {1, 2, 3, 4, 5};
|
||||
array<Type, Size> a;
|
||||
array<int,5> arr= {1, 2, 3, 4, 5};
|
||||
```
|
||||
### 特殊使用方法
|
||||
|
||||
* 值不能改变。不支持插入、删除操作。push/insert/emplace/erase/pop
|
||||
* 与数组完全一致,只是定义方式不同。数组不能copy赋值,但是array可以copy赋值。
|
||||
|
||||
## 2 vector
|
||||
### 特殊原理说明
|
||||
|
||||
* **连续存储结构**,每个元素在内存上是连续的;支持 **高效的随机访问和在尾端插入/删除操作**,但其他位置的插入/删除操作效率低下; 相当于一个数组,但是**与数组的区别为:内存空间的扩展**。vector支持不指定vector大小的存储,但是数组的扩展需要程序员自己写。
|
||||
* vector的内存分配实现原理:STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数返回的大小,当超过此分配的空间时再整体重新放分配一块内存存储( VS6.0是两倍,VS2005是1.5倍),所以 这给人以vector可以不指定vector即一个连续内存的大小的感觉。通常此默认的内存分配能完成大部分情况下的存储。扩充空间(不论多大)都应该这样做:
|
||||
1. 配置一块新空间
|
||||
2. 将旧元素一一搬往新址
|
||||
3. 把原来的空间释放还给系统
|
||||
* vector 的数据安排以及操作方式,与array 非常相似。两者的唯一差别在于空间的利用的灵活性。Array 的扩充空间要程序员自己来写。
|
||||
|
||||
|
||||
### 特殊使用方法
|
||||
|
||||
* 最普通的容器。
|
||||
* 不支持front头部的修改操作(pop_front(),push_front(),emplace_front())。只支持尾部back的操作。
|
||||
|
||||
## 3 deque
|
||||
### 特殊原理说明
|
||||
|
||||
## 4 foward_list
|
||||
### foward_list的特殊操作
|
||||
* **连续存储结构**,即其每个元素在内存上也是连续的,类似于vector,不同之处在于, **deque提供了两级数组结构**, 第一级完全类似于vector,代表实际容器;另一级维护容器的首位地址。这样,deque除了具有vector的所有功能外, 还支持高效的首/尾端插入/删除操作。
|
||||
* deque双端队列 double-end queue。deque是在功能上合并了vector和list。
|
||||
* 优点
|
||||
* 随机访问方便,即支持[ ]操作符和vector.at()
|
||||
* 在内部方便的进行插入和删除操作
|
||||
* 可在两端进行push、pop
|
||||
* 缺点
|
||||
* 占用内存多
|
||||
* 使用区别:
|
||||
* 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
|
||||
* 如果你需要大量的插入和删除,而不关心随机存取,则应使用list
|
||||
* 如果你需要随机存取,而且关心两端数据的插入和删除,则应使用deque
|
||||
### 特殊使用方法
|
||||
* 最全面的容器操作
|
||||
* 支持front头部操作和back尾部操作。
|
||||
|
||||

|
||||
## 5 list
|
||||
## 4 list
|
||||
|
||||
### 特殊原理说明
|
||||
* 非连续存储结构,具有双链表结构,每个元素维护一对前向和后向指针,因此支持前向/后向遍历。 支持高效的随机插入/删除操作,但随机访问效率低下,且由于需要额外维护指针 ,开销也比较大。每一个结点都包括一个信息快Info、一个前驱指针Pre、一个后驱指针Post。可以不分配必须的内存大小方便的进行添加和删除操作。使用的是非连续的内存空间进行存储。
|
||||
* 优点:
|
||||
* 不使用连续内存完成动态操作。
|
||||
* 在内部方便的进行插入和删除操作
|
||||
* 可在两端进行push、pop
|
||||
* 缺点:
|
||||
* 不能进行内部的随机访问,即不支持[ ]操作符和vector.at()
|
||||
* 相对于verctor占用内存多
|
||||
* 使用区别:
|
||||
* 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
|
||||
* 如果你需要大量的插入和删除,而不关心随机存取,则应使用list
|
||||
* 如果你需要随机存取,而且关心两端数据的插入和删除,则应使用deque
|
||||
|
||||
### 特殊使用方法
|
||||
* 最全面的容器操作。不支持随机容器访问at和[]运算符。
|
||||
* list的迭代器只能进行++/--。不能进行算数运算。
|
||||
* 支持front、back的操作。
|
||||
* 支持的额外操作如下(这些操作大部分在泛型算法中实现过了)
|
||||
|
||||
方法|说明
|
||||
|----|----|
|
||||
|void remove( T val)|删除所有和val相等的元素。
|
||||
|void splice(iterator,list)|将整个链表插入到指定位置。原来的链表删除。
|
||||
|void splice(iterator,list,iterator)|将链表中指定位置的元素插入到list的list的位置。原来链表的指定元素删除。
|
||||
|void splice(iterator,list,iterator begin,iterator end|将链表begin和end之间的元素插入到指定位置。|
|
||||
|void merge(list)|两个链表必须是有序链表。按照默认的顺序进行归并操作。归并排序使用。原来的链表删除。|
|
||||
|void merge(list,cmp)|两个链表必须是有序链表。按照cmp中定义的大小关系进行归并操作。归并排序使用。
|
||||
|void reverse(void)|反转容器
|
||||
|sort()|对链表进行排序。
|
||||
|sort(cmp)|使用比较函数对链表进行排序。
|
||||
|unique()|移除连续且相同的元素
|
||||
|
||||
|
||||
## 5 forward_list
|
||||
### 特殊使用方法
|
||||
* 因为forward_list是单向链表。所以提供了很多特殊操作。因为它无法访问到之前的元素。所以必须在前一个元素对下一个元素操作。
|
||||
* 提供了一系列before、after
|
||||
* 其他的操作是list操作的子集。
|
||||
* 支持front的操作。但不支持back端的操作。
|
||||
|
||||
方法|说明
|
||||
|----|----|
|
||||
|iterator before_begin()|首元素之前不存在的元素。|
|
||||
|iterator cbefore_begin()|const的首迭代器。|
|
||||
|emplace_after(p,args)|指定位置插入|
|
||||
|insert_after(iterator p,T val)|在指定位置之后,单个元素插入。forward_list的特殊版本。在元素之后插入。|
|
||||
|insert_after(iterator p,int n,T val)|在指定位置之后,n个val值的插入。forward_list 的特殊版本。在元素之后范围插入。|
|
||||
|insert_after(iterator p,iterator begin,iterator end)|在指定位置之后。forward_list的特殊版本。插入begin,end范围内的元素。|
|
||||
|insert_after(iterator p,{a,b,c,})|在指定位置之后。forward_list的特殊版本。插入列表范围内的元素。|
|
||||
|erase_after(iterator p)|删除指定位置的元素|
|
||||
|erase_after(iterator b,iterator e)|删除指定范围的元素|
|
||||
|
||||
|
||||
<!--  -->
|
||||
|
||||
## 6 容器常见的问题
|
||||
|
||||
### 6.1 list和vector的区别:
|
||||
1. vector为存储的对象分配一块连续的地址空间 ,随机访问效率很高。但是 插入和删除需要移动大量的数据,效率较低。尤其当vector中存储的对象较大,或者构造函数复杂,则在对现有的元素进行拷贝的时候会执行拷贝构造函数。
|
||||
2. list中的对象是离散的,随机访问需要遍历整个链表, 访问效率比vector低。但是在list中插入元素,尤其在首尾 插入,效率很高,只需要改变元素的指针。
|
||||
3. vector是单向的,而list是双向的;
|
||||
4. 向量中的iterator在使用后就释放了,但是链表list不同,它的迭代器在使用后还可以继续用;链表特有的;
|
||||
|
||||
5. 使用原则:
|
||||
1. 如果需要高效的随机存取,而不在乎插入和删除的效率,使用vector;
|
||||
2. 如果需要大量高效的删除插入,而不在乎存取时间,则使用list;
|
||||
3. 如果需要搞笑的随机存取,还要大量的首尾的插入删除则建议使用deque,它是list和vector的折中;
|
||||
|
||||
### 6.2 常量容器const
|
||||
* const vector<int> vec(10);//这个容器里 capacity和size和值都是不能改变的, const修饰的是vector;
|
||||
* 迭代器:const vector<int>::const_iterrator ite; //常量迭代器;
|
||||
|
||||
### 6.3 capacity与size
|
||||
* capacity是容器需要增长之前,能够盛的元素总数; 只有连续存储的容器才有capacity的概念(例如vector,deque,string),list不需要capacity。
|
||||
* size是容器当前存储的元素的数目。
|
||||
* vector默认的容量初始值,以及增长规则是依赖于编译器的。
|
||||
|
||||
### 6.4 用vector存储自定义类对象时,自定义类对象须满足:
|
||||
* 有可供调用的无参构造函数(默认的或自定义的);
|
||||
* 有可用的拷贝赋值函数(默认的或自定义的)
|
||||
|
||||
### 6.5迭代器iterator
|
||||
|
||||
* vector与deque的迭代器支持算术运算,**list的迭代器只能进行++/--**操作,不支持普通的算术运算。
|
||||
* 向量中的iterator在使用后就释放了,但是链表list不同,它的迭代器在使用后还可以继续用;链表特有的;
|
||||
194
C++/标准库/2.1.cpp
Normal file
194
C++/标准库/2.1.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#include<vector>
|
||||
#include<list>
|
||||
#include<deque>
|
||||
#include<forward_list>
|
||||
#include<iostream>
|
||||
#include<algorithm>
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
|
||||
vector<int> vec{1,2,3};
|
||||
int n=10;
|
||||
// 下表与迭代器的转换方式如下
|
||||
vector<int>::iterator it = vec.begin();
|
||||
if(*(it+n)==vec[n])cout<<boolalpha<<true<<endl;
|
||||
|
||||
|
||||
vec.insert(vec.begin()+2,{1,2,3});
|
||||
for(auto a:vec){
|
||||
cout<<a<<endl;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int test_vector()
|
||||
{
|
||||
vector <int> vec(5,8);
|
||||
//--类型是vector<int>,该容器向量中含有5个int类型的数值8,变量名为vec。
|
||||
//vector是一个类模板(class template),所以必须要声明其类型,int,一个容器中所有的对象必须是同一种类型;
|
||||
// 定义一个容器对象;直接构造出一个数组;用法和数组一样;
|
||||
//
|
||||
for(int i=0;i<vec.size();i++) //size()是指容器里当前有多少个使用的元素;
|
||||
{
|
||||
cout<<vec[i]<<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl; //得到容器里用的多少个空间,和总共的大小;
|
||||
vector<int>::iterator ite; //定义了一个向量的迭代器;相当于定义了一个指针;
|
||||
for(ite=vec.begin();ite!=vec.end();ite++) //得到开始、结束
|
||||
{
|
||||
cout<<*ite <<" "; //迭代器返回的是引用:
|
||||
}
|
||||
cout<<endl;
|
||||
//在尾部插入;
|
||||
vec.push_back(9); //VS6.0扩充的空间是两倍;在VS2005扩充的空间是1.5倍;
|
||||
for(ite=vec.begin();ite!=vec.end();ite++) //得到开始、结束
|
||||
{
|
||||
cout<<*ite <<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl;
|
||||
|
||||
//尾部删除;容量没变【capacitty】,但是使用空间减少一个;容量一旦增加就不会减小;
|
||||
vec.pop_back();
|
||||
for(ite=vec.begin();ite!=vec.end();ite++) //得到开始、结束
|
||||
{
|
||||
cout<<*ite <<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl;
|
||||
|
||||
vec.push_back(88);
|
||||
vec.push_back(99); //容量刚好够;
|
||||
|
||||
for(ite=vec.begin();ite!=vec.end();ite++) //得到开始、结束
|
||||
{
|
||||
cout<<*ite <<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl;
|
||||
|
||||
ite = find(vec.begin(),vec.end(),88); //查找这个元素;
|
||||
vec.erase(ite); //利用迭代器指针删除这个元素;
|
||||
for(int i=0;i<vec.size();i++) //size()是指容器里当前有多少个使用的元素;
|
||||
{
|
||||
cout<<vec[i]<<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl; //得到容器里用的多少个空间,和总共的大小;
|
||||
|
||||
vec.clear(); //只是清除了数据,没有回收空间,空间的等到对象的生命周期结束时回收;
|
||||
//使用空间为0,但是容量的空间还在,只有在调用析构函数的时候空间才会回收;
|
||||
|
||||
for(int i=0;i<vec.size();i++) //size()是指容器里当前有多少个使用的元素;
|
||||
{
|
||||
cout<<vec[i]<<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl;
|
||||
|
||||
ite=find(vec.begin(),vec.end(),88);
|
||||
vec.insert(ite,2,77); //迭代器标记的位置前,插入数据;
|
||||
|
||||
//cout<<*ite<<endl; //会崩溃,因为迭代器在使用后就释放了,*ite的时候就找不到它的地址了;
|
||||
//和向量的用法一样,但是链表list不同,它的迭代器在使用后还可以继续用;链表特有的;</span>
|
||||
|
||||
for(int i=0;i<vec.size();i++)
|
||||
{
|
||||
cout<<vec[i]<<" ";
|
||||
}
|
||||
cout<<endl<<vec.size()<<" "<<vec.capacity()<<endl;
|
||||
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
int test_list()
|
||||
{
|
||||
list<char> lit;
|
||||
//用法和向量一样,
|
||||
//list是一个类模板,template,char是链表里对象的类型,lit是创建的一个对象;
|
||||
//链表可以再头尾两端插入,是双向的;
|
||||
|
||||
lit.push_back('a');
|
||||
lit.push_back('b');
|
||||
lit.push_front('d');
|
||||
lit.push_front('e');
|
||||
lit.push_front('f');
|
||||
lit.push_front('b');
|
||||
lit.push_front('b');
|
||||
|
||||
list<char>::iterator it; //定义一个list的迭代器,类似一个纸箱链表的指针,但是比一般的指针好用,里面用到了好多重载操作;
|
||||
list<char>::iterator it1;
|
||||
list<char>::iterator it2;
|
||||
for(it=lit.begin();it!=lit.end();it++)
|
||||
{
|
||||
cout<<*it<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
//-----------链表可以从两端删除-------------------
|
||||
lit.pop_back();
|
||||
lit.pop_front();
|
||||
for(it=lit.begin();it!=lit.end();it++)
|
||||
{
|
||||
cout<<*it<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
//-------------删除所有的a---------------------------------
|
||||
//lit.remove('a'); //删除所有的a;
|
||||
|
||||
for(it=lit.begin();it!=lit.end();it++)
|
||||
{
|
||||
cout<<*it<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
//-------------移除连续且相同的a,只剩下一个;--------------------------------
|
||||
lit.unique(); //移除连续且相同的a,只剩下一个;
|
||||
|
||||
for(it=lit.begin();it!=lit.end();it++)
|
||||
{
|
||||
cout<<*it<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
list<char> lit1;
|
||||
lit1.push_back('g');
|
||||
lit1.push_back('h');
|
||||
lit1.push_back('i');
|
||||
lit1.push_back('k');
|
||||
for(it1=lit1.begin();it1!=lit1.end();it1++)
|
||||
{
|
||||
cout<<*it1<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
//-------------将一个链表插入到另一个链表---------------------------------
|
||||
it1=find(lit.begin(),lit.end(),'f'); //先的找到要插入的位置,在该位置的前一个插入;
|
||||
lit.splice(it1,lit1); //将第二个链表插入到第一个链表中;合并后的链表就没了,因为传的是&;
|
||||
for(it=lit.begin();it!=lit.end();it++)
|
||||
{
|
||||
cout<<*it<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
//------在链表lit中的it前插入lit1中的一个元素it1;在f之前插入k-----
|
||||
//-----拿下来之后那个元素就没有了-------------------
|
||||
it=find(lit.begin(),lit.end(),'f');
|
||||
it1=find(lit1.begin(),lit1.end(),'k');
|
||||
lit.splice(it,lit1,it1);
|
||||
//-------------把链表中的一段插入到另一个链表中---------------------------------
|
||||
//把链表lit1中的[it-----it1)段的字符插入到lit的it2指针前;
|
||||
it=find(lit1.begin(),lit1.end(),'h');
|
||||
it1=find(lit1.begin(),lit1.end(),'k');
|
||||
it2=find(lit.begin(),lit.end(),'f');
|
||||
lit.splice(it2,lit1,it,it1);
|
||||
// ----void merge(list& x); //将x合并到*this 身上。两个lists 的内容都必须先经过递增归并排序。
|
||||
lit.sort(); //对两个排序进行归并排序;
|
||||
lit1.sort();
|
||||
lit.merge(lit1);
|
||||
//-----------将list里的数据倒序排列---------------
|
||||
lit.reverse();
|
||||
for(it=lit.begin();it!=lit.end();it++)
|
||||
{
|
||||
cout<<*it<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
for(it1=lit1.begin();it1!=lit1.end();it1++)
|
||||
{
|
||||
cout<<*it1<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
# 关联容器
|
||||
|
||||
|
||||
## 1 关联容器概述
|
||||
## 0 关联容器概述
|
||||
|
||||
### 关联容器与顺序容器的区别
|
||||
|
||||
关联容器和顺序容器有着根本不同。关联容器中的元素是按关键字来把偶才能和访问的。书序容器中的元素是按他们在容器中的位置来顺序保存和访问的。
|
||||
* 关联容器和顺序容器有着根本不同。关联容器中的元素是按关键字来把偶才能和访问的。书序容器中的元素是按他们在容器中的位置来顺序保存和访问的。
|
||||
|
||||
### 两个基础类型
|
||||
|
||||
@@ -27,127 +27,107 @@
|
||||
* `<unorder_map>`:unorder_map,unorder_multimap
|
||||
* `<unorder_set>`:unorder_set,unorder_multiset
|
||||
|
||||
### map和set的使用
|
||||
|
||||
```
|
||||
#include<iostream>
|
||||
#include<map>
|
||||
#include<set>
|
||||
### 有序关联容器的原理
|
||||
* 有序关联容器的底层一般使用红黑树实现。
|
||||
* 泛型算法通常不对关联容器使用
|
||||
|
||||
using namespace std;
|
||||
### 无序关联容器的原理
|
||||
* 一般使用hash表实现存储。
|
||||
|
||||
int main(){
|
||||
|
||||
map<string,int> word_count;
|
||||
string word="hello";
|
||||
word_count[word]=10;
|
||||
word_count["world"]=35;
|
||||
//遍历map
|
||||
for(auto &w:word_count){
|
||||
cout<<"w.first"<<w.second<<endl;
|
||||
}
|
||||
|
||||
|
||||
//set
|
||||
set<string> ss{"yin","kang","long","hello","world"};
|
||||
for (auto s : ss)
|
||||
{
|
||||
cout<<s<<endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### 定义关联容器
|
||||
## 1 关联容器的通用操作
|
||||
|
||||
### 1.1 初始化
|
||||
* 与容器部分的初始化一致。支持六种基本的初始化方法。默认初始化、值初始化、直接初始化、赋值初始化、列表初始化、迭代器初始化。**不支持**constructor(n)和constructor(n,t)的初始化。
|
||||
* map、set的定义和初始化
|
||||
```
|
||||
map<string,int> word_count;//空容器
|
||||
set<string> ex{"the","to"};//初始化set
|
||||
map<string,int> wc{
|
||||
{"jo",10},
|
||||
{"yin",13},
|
||||
{"kang",53},
|
||||
{"long",3}
|
||||
};//初始化map
|
||||
```C++
|
||||
map<string,int> word_count;//空容器
|
||||
set<string> ex{"the","to"};//初始化set
|
||||
map<string,int> wc{
|
||||
{"jo",10},
|
||||
{"yin",13},
|
||||
{"kang",53},
|
||||
{"long",3}
|
||||
};//初始化map
|
||||
```
|
||||
* multimap、multiset的定义和初始化。允许关键字的重复。
|
||||
|
||||
```
|
||||
//可以使用顺序容器初始化关联容器multiset初始化
|
||||
vector<int> vec{1,2,3,4,5,5,4,3,2,1};
|
||||
set<int> iset(vec.begin(),vec.end());
|
||||
multiset<int> mset(vec.begin(),vec.end());
|
||||
cout<<iset.size()<<endl;
|
||||
cout<<mset.size()<<endl;
|
||||
```C++
|
||||
//可以使用顺序容器初始化关联容器multiset初始化
|
||||
vector<int> vec{1,2,3,4,5,5,4,3,2,1};
|
||||
set<int> iset(vec.begin(),vec.end());
|
||||
multiset<int> mset(vec.begin(),vec.end());
|
||||
cout<<iset.size()<<endl;
|
||||
cout<<mset.size()<<endl;
|
||||
```
|
||||
|
||||
### pair类型
|
||||
|
||||
* 类似容器,pair是用来生成特定类型的模板。
|
||||
* 定义pair
|
||||
|
||||
## 2.1 有序关联容器-map
|
||||
### 存储内容
|
||||
```
|
||||
pair<string,string> author{'James","joyce"};
|
||||
pair<key,value>
|
||||
```
|
||||
### 访问元素
|
||||
|
||||
* pair上的操作
|
||||
方法|说明
|
||||
|---|---|
|
||||
[key]|map的下标访问运算符。返回pair的值。如果没有该键。则会创建该键。
|
||||
at(key)|map的键访问运算符。返回pair值。如果没有该键。会抛出异常。
|
||||
iterator find(key)|找到某个键。返回指向该键的迭代器。
|
||||
int count(key)|计算某个键的数量。返回该键出现的数量。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 2 关联容器的基础操作
|
||||
|
||||
### 关联容器额外的类型名
|
||||

|
||||
|
||||
|
||||
### 关联容器的迭代器和元素遍历
|
||||
|
||||
```
|
||||
//使用迭代器遍历关联容器
|
||||
|
||||
auto map_it = word_count.cbegin();
|
||||
while(map_it != word_count.cend()){
|
||||
cout<<map_it->first<<map_it->second<<endl;
|
||||
map_it++;
|
||||
}
|
||||
```
|
||||
|
||||
### 关联容器的算法
|
||||
|
||||
* 我们通常不对关联容器使用泛型算法
|
||||
<!--  -->
|
||||
|
||||
### 添加元素
|
||||
|
||||

|
||||
* 关联容器的插入操作。通常不需要指定位置。
|
||||
* 对于map和set而言。只有当关键字不在容器当中时才会进行插入。如果存在该元素则插入失败。
|
||||
|
||||
|
||||
方法| 说明
|
||||
|----|----|
|
||||
`pair<iterator,bool>` emplace(args)|使用args初始化一个值。插入到关联容器中。iterator指向插入的元素。bool指示是否插入成功。
|
||||
`pair<iterator,bool>`insert(val)|插入值为val的元素。
|
||||
`pair<iterator,bool>`insert(iterator begin,iterator end)|插入指定范围的元素。
|
||||
`pair<iterator,bool>`insert({a,b,c,})|插入初值列表中的元素。
|
||||
insert(p,v) |迭代器只起到提示作用。返回值为迭代器,指向给定关键字的元素
|
||||
emplace(p,args)|迭代器起到提示作用。插入元素。返回值为迭代器。指向给定关键字的元素。
|
||||
|
||||
<!--  -->
|
||||
|
||||
### 删除元素
|
||||
|
||||

|
||||
方法|说明
|
||||
|----|----|
|
||||
int erase(key)|删除关键字为k的元素。返回删除的元素的数量。
|
||||
iterattor erase(iterator p)|删除迭代器p指向的元素。返回指向下一个元素的迭代器。这种东西都是遍历删除的时候用的。
|
||||
erase(iterator begin(),iterator end())|删除范围内的元素。返回结尾e指向的元素。
|
||||
|
||||
### map下标操作
|
||||
<!--  -->
|
||||
|
||||

|
||||
|
||||
### 访问元素
|
||||
|
||||

|
||||
## 2.2 有序管理容器-set
|
||||
### 存储内容
|
||||
```
|
||||
key
|
||||
```
|
||||
### 访问操作
|
||||
* 不支持[]和at()访问元素。支持find和count
|
||||
### 添加操作
|
||||
* 与map一样。只不过操作类型不是pair,而是单个的key
|
||||
### 删除操作
|
||||
* 与map一样。只不过操作类型不是pair,而是单个的key
|
||||
|
||||
|
||||
## 3 无序关联容器的基础操作
|
||||
## 3 无序关联容器
|
||||
|
||||
### 说明
|
||||
|
||||
* 不适用比较运算符来组织元素,使用哈希函数和关键字类型的==运算符。
|
||||
* 使用无序容器通常更简单,具有更好的效果。
|
||||
* 底层是通过哈希函数实现的。所以有很多关于哈希函数的处理操作。
|
||||
|
||||
### 基础操作
|
||||
|
||||
* 与有序容器一样,包括find、insert
|
||||
* 与有序关联容器一样
|
||||
|
||||
### 管理桶
|
||||
* 无序关联容器相对于普通关联容器的特殊操作。
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
using namespace std;
|
||||
|
||||
int main(){
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void test_map(){
|
||||
map<string,int> word_count;//空容器
|
||||
set<string> ex{"the","to"};//初始化set
|
||||
map<string,int> wc{
|
||||
@@ -25,23 +29,7 @@ int main(){
|
||||
cout<<"w.first"<<w.second<<endl;
|
||||
}
|
||||
|
||||
|
||||
//set
|
||||
set<string> ss{"yin","kang","long","hello","world"};
|
||||
for (auto s : ss)
|
||||
{
|
||||
cout<<s<<endl;
|
||||
}
|
||||
|
||||
//可以使用顺序容器初始化关联容器multiset初始化
|
||||
vector<int> vec{1,2,3,4,5,5,4,3,2,1};
|
||||
set<int> iset(vec.begin(),vec.end());
|
||||
multiset<int> mset(vec.begin(),vec.end());
|
||||
cout<<iset.size()<<endl;
|
||||
cout<<mset.size()<<endl;
|
||||
|
||||
//使用迭代器遍历关联容器
|
||||
|
||||
auto map_it = word_count.cbegin();
|
||||
while(map_it != word_count.cend()){
|
||||
cout<<map_it->first<<map_it->second<<endl;
|
||||
@@ -57,6 +45,22 @@ int main(){
|
||||
cout<<people["yin"]<<endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_set(){
|
||||
|
||||
//set
|
||||
set<string> ss{"yin","kang","long","hello","world"};
|
||||
for (auto s : ss)
|
||||
{
|
||||
cout<<s<<endl;
|
||||
}
|
||||
|
||||
//可以使用顺序容器初始化关联容器multiset初始化
|
||||
vector<int> vec{1,2,3,4,5,5,4,3,2,1};
|
||||
set<int> iset(vec.begin(),vec.end());
|
||||
multiset<int> mset(vec.begin(),vec.end());
|
||||
cout<<iset.size()<<endl;
|
||||
cout<<mset.size()<<endl;
|
||||
|
||||
}
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
## 1 泛型算法概览
|
||||
|
||||
|
||||
|
||||
### 说明
|
||||
|
||||
* 容器的**迭代器**使得算法不依赖于容器。但算法依赖于元素类型的操作。
|
||||
@@ -36,10 +34,12 @@
|
||||
beg|开始迭代器
|
||||
end|终止迭代器
|
||||
val|值
|
||||
func|操作函数
|
||||
n|整数
|
||||
comp|比较函数,返回true/false
|
||||
binary|判断函数,返回true/false
|
||||
func|操作函数。用于操作。
|
||||
pred |==比较函数。返回true/false。用于搜索。
|
||||
cmp|大小比较函数,返回true/false。用于排序。
|
||||
binary|判断函数,返回true/false。用于判断。
|
||||
|
||||
|
||||
## 1.1 基础算法(遍历算法)
|
||||
|
||||
@@ -58,9 +58,9 @@ binary|判断函数,返回true/false
|
||||
|
||||
| 函数 | 作用 |
|
||||
|---|---|
|
||||
| for_each(beg,end,func) | 将[beg,end)范围内所有元素依次调用函数func,返回func。不修改序列中的元素。 |
|
||||
| transform(beg,end,res,unary) | 将[beg,end)范围内所有元素依次调用函数unary,结果放入res中。 |
|
||||
| transform(beg1,end1,beg2,res,binary) | 将[beg,end)范围内所有元素与[beg2,beg2+end-beg)中所有元素依次调用函数unary,结果放入res中。 |
|
||||
| for_each(beg,end,func) | 将[beg,end)范围内所有元素依次调用函数func,返回func。可以使用func修改序列中的元素。但必须传递引用参数 |
|
||||
| transform(beg,end,res,func) | 将[beg,end)范围内所有元素依次调用函数unary,结果放入res中。 |
|
||||
| transform(beg1,end1,beg2,res,binary) | 将[beg,end)范围内所有元素与[beg2,beg2+end-beg)中所有元素依次调用函数binary,结果放入res中。 |
|
||||
|
||||
### 最大最小
|
||||
| 函数 | 作用 |
|
||||
@@ -85,7 +85,7 @@ binary|判断函数,返回true/false
|
||||
| 函数 | 作用 |
|
||||
|---|---|
|
||||
| sort(beg,end) | 默认升序重新排列元素 |
|
||||
| sort(beg,end,comp) | 使用函数comp代替比较操作符执行sort()。 |
|
||||
| sort(beg,end,comp) | 使用函数comp代替比较操作符执行sort()。排序sort使用快排进行排序。排序过程中的cmp表示是否将第一个参数移到第二个参数之前。如果是true则会发生移动。如果不是true则不会发生移动。 |
|
||||
| partition(beg,end,pred) | 元素重新排序,使用pred函数,把结果为true的元素放在结果为false的元素之前。 |
|
||||
| stable_sort(beg,end) | 与sort()类似,保留相等元素之间的顺序关系。 |
|
||||
| stable_sort(beg,end,pred) | 使用函数pred代替比较操作符执行stable_sort()。 |
|
||||
@@ -93,8 +93,8 @@ binary|判断函数,返回true/false
|
||||
| stable_partition(beg,end,pred) | 使用函数pred代替比较操作符执行stable_partition()。 |
|
||||
| partial_sort(beg,mid,end) | 部分排序,被排序元素个数放到[beg,end)内。 |
|
||||
| partial_sort(beg,mid,end,comp) | 使用函数comp代替比较操作符执行partial_sort()。 |
|
||||
| partial_sort_copy(beg1,end1,beg2,end2) | 与partial_sort()类似,只是将[beg1,end1)排序的序列复制到[beg2,end2)。 |
|
||||
| partial_sort_copy(beg1,end1,beg2,end2,comp) | 使用函数comp代替比较操作符执行partial_sort_copy()。 |
|
||||
| partial_sort_copy (beg1,end1,beg2,end2) | 与partial_sort()类似,只是将[beg1,end1)排序的序列复制到[beg2,end2)。 |
|
||||
| partial_sort_copy (beg1,end1,beg2,end2,comp) | 使用函数comp代替比较操作符执行partial_sort_copy()。 |
|
||||
| nth_element(beg,nth,end) | 单个元素序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面。 |
|
||||
| nth_element(beg,nth,end,comp) | 使用函数comp代替比较操作符执行nth_element()。 |
|
||||
|
||||
|
||||
@@ -17,15 +17,22 @@ void unique_sort(vector<int> &words){
|
||||
int main(){
|
||||
vector<int> n{4,2,5,2,5,6,7};
|
||||
|
||||
for(int m :n){
|
||||
cout<<m<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
unique_sort(n);
|
||||
// for(int m :n){
|
||||
// cout<<m<<" ";
|
||||
// }
|
||||
// cout<<endl;
|
||||
// unique_sort(n);
|
||||
|
||||
for(int m :n){
|
||||
cout<<m<<" ";
|
||||
}
|
||||
cout<<endl;
|
||||
// for(int m :n){
|
||||
// cout<<m<<" ";
|
||||
// }
|
||||
// cout<<endl;
|
||||
for_each(n.begin(),n.end(),[](int &a){
|
||||
a=1;
|
||||
return;
|
||||
});
|
||||
for_each(n.begin(),n.end(),[](int&a){
|
||||
cout<<a<<endl;
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,12 @@
|
||||
# 计划
|
||||
1. 学习动态规划
|
||||
2. 学习C++库函数的使用。对模板算法的第三个参数进行总结。
|
||||
3. 学习机器学习的实现方案。
|
||||
4. 需要重新看一下补码、原码相关的加减法操作。
|
||||
1. 对刷题的内容进行总结。
|
||||
2. 学习、复习动态规划
|
||||
3. 学习、复习回溯剪枝
|
||||
4. 学习、复习分支限界
|
||||
5. √学习C++容器。对容器的构造函数进行总结。
|
||||
6. √学习C++容器。对每个容器的基础操作进行总结。
|
||||
7. √学习C++模板算法。对算法的第三个参数进行总结。
|
||||
8. 需要重新看一下补码、原码相关的加减法操作。
|
||||
|
||||
|
||||
# 收获
|
||||
@@ -10,4 +14,5 @@
|
||||
* 学会了sort的第三个参数的应用
|
||||
* (学会了动态规划,进行了总结)
|
||||
* 内存的直接copy要比循环赋值快的多。比如在vector.erase中删除一个元素。剩下的元素会直接通过内存拷贝的方式移动到前边。insert 后会直接内存拷贝移动到后边。
|
||||
* 例如数组初始化的时候。可以通过内存拷贝实现初始化。而非通过循环一个个赋值。
|
||||
* 例如数组初始化的时候。可以通过内存拷贝实现初始化。而非通过循环一个个赋值。vector中提供了统一元素复制的构造函数constructor(n,t)。通过assign(n,t)函数或者其他方式进行初始化,远远比循环初始化快的多得多。顺序容器中提供了范围插入的方法。
|
||||
* 应该对数组的迭代器(指向元素的指针)进行更熟练的使用。
|
||||
14
工作日志/2021年3月18日-今日计划.md
Normal file
14
工作日志/2021年3月18日-今日计划.md
Normal file
@@ -0,0 +1,14 @@
|
||||
## 计划
|
||||
1. 动手实现所有的图算法。
|
||||
2. 看完数据结构与算法的三本书!!!对相关的原理进行复习和总结。
|
||||
3. 学习机器学习的实现方案。毕设计划真正的开始执行。
|
||||
|
||||
## 收获
|
||||
|
||||
|
||||
|
||||
|
||||
## 月总结
|
||||
> 第一周时间完成了C++语法、C++标准库、C++面向对象的总结。
|
||||
> 第二周时间完成了数据结构的复习。用两天时间复习了基础的数据结构。然后开始刷题。上周二、周三。一边刷题。一边总结了数据结构相关的代码。一边对算法基础、递归迭代、深度广度搜索进行了总结。对具体的算法的总结还么有开始。
|
||||
> 然后刷题一直到现在。数据结构和算法一直复习到现在不过分。
|
||||
@@ -7,9 +7,9 @@
|
||||
符号|说明
|
||||
|----|----|
|
||||
& | 按位与
|
||||
\| | 按位或
|
||||
^ | 按位异或
|
||||
~ | 按位取反
|
||||
| | 按位或
|
||||
\~ | 按位取反
|
||||
\>\> | 右移
|
||||
<< | 左移
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
操作 | 性质
|
||||
|-----| -----|
|
||||
n & (n - 1) | n中的最后一个1变成0
|
||||
^抑或运算 | 相同的数抑或运算等于零。不同的数抑或运算等于1
|
||||
^ | 相同的数抑或运算等于零。不同的数抑或运算等于1
|
||||
n/2 | 等价于 右移一位 n >> 1
|
||||
n*2 | 等价于 左移一位 n << 1
|
||||
n % 2 |等价于 判断二进制最右一位值 n \& 1
|
||||
@@ -57,4 +57,18 @@ int quickMulti(int A, int B) {
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
```
|
||||
|
||||
### 快速加法
|
||||
|
||||
```
|
||||
int add(int a,int b){
|
||||
cout<<(unsigned int)-1<<endl;
|
||||
while(b != 0) { // 当进位为 0 时跳出
|
||||
int c = ((unsigned int)(a & b)) << 1; // c = 进位
|
||||
a ^= b; // a = 非进位和
|
||||
b = c; // b = 进位
|
||||
}
|
||||
return a;
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user