《STL源码剖析》阅读笔记1
来源:互联网 发布:网络电缆测试仪上电池 编辑:程序博客网 时间:2024/05/29 19:57
排列组合算法
next_permutation
作用:获得[first,last)所表示序列的下一个排列组合
如果没有,返回false;
否则返回true
算法:
1- 从最尾端往前搜索两个相邻元素,零第一个元素为*i,第二个为*ii,并满足:*i<*ii;
2- 再从尾端开始往前检验,找出第一个大于*i的元素,令为*j,对调i,j指向元素;
3- 将ii后的所有元素颠倒
例子
char*版本代码:
bool next_permutation(char*first,char*last)
{
if(first==last)return false;//空区间
char *i=first;
++i;
if(i==last)return false;//只有一个元素
i=last;//尾端
--i;
for(;;)
{
char *ii=i;
--i;
if(*i<*ii)
{
char *j=last;
while(!(*i<*--j));
swap(*i,*j);
reverse(ii,last);
return true;
}
if(i==first)
{
reverse(first,last);
return false;
}
}
}
prev_ permutation
算法:
1-尾端往前搜索两个相邻元素,零第一个元素为*i,第二个为*ii,并满足:*i>*ii;
2-端开始往前检验,找出第一个小于素,令为*j,对调i,j指向元素;
3-ii的所有元素颠倒
char*版本:
bool prev_permutation(char*first,char*last)
{
if(first==last)return false;//空区间
char *i=first;
++i;
if(i==last)return false;//只有一个元素
i=last;//尾端
--i;
for(;;)
{
char *ii=i;
--i;
if(*i>*ii)
{
char *j=last;
while(!(*i>*--j));
swap(*i,*j);
reverse(ii,last);
return true;
}
if(i==first)
{reverse(first,last);return false;}
}
}
随机重排数组
random_shuffle
for i=1~n-1
swap(a[i],a[rand()%(i+1)])
快速计算x的n次幂 power()的实现
x^n(n>=0)
template <class T>
T power (T x,int n)
{
if(n==0)return 1;
else
{
Tresult=1;
if(n&1!=0)//n为偶数
{//result=x,n=n-1或者n=n&0;
result=x;n=n&0;
}
//n为奇数或偶数时的公共部分
while(n&1==0)
{
x=x*x;
n>>=1;
}
result*=x;
}
return result;
}
模仿STL的版本
template <class T>
T power (T x,int n)
{
if(n==0)return 1;
else
{
while((n&1==0))//偶数
{
n>>=1;
x=x*x;
}
T result=x;
n>>=1;
while(n!=0)
{
x=x*x;
if(n&1!=0)奇数
result=result*x;
n>>=1;
}
result
}
}
heap算法和优先级队列
push_heap(first,last)
pop_heap(first,last){adjust_heap}
sort_heap(first,last){一直使用pop_heap直至没有元素为止}
make_heap(first,last){调用adjust_heap}
建立堆
make_heap(_First,_Last, _Comp)
1-默认是建立最大堆的。
在堆中添加数据
push_heap(_First, _Last)
要先在容器中加入数据,再调用push_heap ()
在堆中删除数据
pop_heap(_First,_Last)
要先调用pop_heap()再在容器中删除数据
堆排序
sort_heap(_First,_Last)
用法
int a[9]={1-9}:
vector<int>myvec(a,a+9);
make_heap(myvec.begin(),myvec.end());
///直接改变myvec
优先级队列=vector+heap算法
构造函数---make_heap算法,make_heap(c.begin,c.end(),comp)
push---------(1,低层容器的push_back插入末端,
2,使用push_heap算法重排heap, push_heap(c.begin,c.end(),comp)
pop---------(1,重排heap,pop_heap(c.begin,c.end(),comp)
2,底层容器的pop_back()弹出元素, c.pop_back())
自定义类使用优先级队列
通过对结构体重载operator():
1- 定义函数对象
2- 重新定义operator<函数
例子:程序功能是模拟排队过程,每人有姓名和优先级,优先级相同则比较姓名,
开始有5个人进入队列,然后队头2个人出队,再有3个人进入队列,
最后所有人都依次出队,程序会输出离开队伍的顺序。
将上面结构体Node改成类
使用set容纳自定义类/结构体
使用set容纳自定义类/结构体
set模板需要3个泛型参数:
template<class T, class C, class A>class set;
第一个T 是元素类型,必选;
第二个C 指定元素比较方式,缺省为 Less<T>, 即使用 < 符号比较;
第三个A 指定空间分配对象,一般使用默认类型。
因此:对于第2个泛型参数
(1) 如果使用默认值,自定义元素类型需要重载<运算操作;
(2)不使用默认值,则比较对象必须具有() 操作,即自定义函数对象:
bool operator()(const T &a, const T&b)
即自定义一个比较函数/函数对象
map使用自定义类-----看模板参数
所以作为关键字,起码必须有“<”这个比较操作符。
1-int,float,enum,size_t等等简单关键字,都有内置的比较函数,与map搭没什么问题。
2-自定义类型,必须明确定义“<”比较操作符,作为第三个参数。
使用map时,注意以下两点,同时这两点也是改错的方法:
a) 关键字明确定义“<”比较操作符
b) 没有“<”比较操作符,自定义仿函数替代第三个参数Compare,该仿函数实现“()”操作符,提供比较功能。插入时使用
map<pair<int,int>,int,comp>res;
res.insert(make_pair(12,33),33);
res.insert(make_pair(122,333),333);
capacity,size
capacity
容器增长前,能够容纳的元素总数;
只有连续存储的容器才有容量概念(vector,deque,string),list不需要;
size
容器当前存储的元素数量;
注:vector默认的容量初始值,增长规则依赖编译器
vector存储自定义对象
自定义对象必须满足:
1, 默认构造函数(默认或自定义的)
2, 可用的拷贝构造,赋值函数(默认或自定义的)
自己的理解:如果对vector排序的话,还需要定义operator<,==等操作符
deque
双向队列-----双向开口的连续线性空间;
高效的在头尾两端插入和删除元素;
deque的实现
内部会维护一个map(注意!不是STL中的map容器)即一小块连续的空间,该空间中每个元素都是指针,指向另一段(较大的)区域,这个区域称为缓冲区,缓冲区用来保存deque中的数据。因此deque在随机访问和遍历数据会比vector慢。
注意一点。对于deque和vector来说,尽量少用erase(pos)和erase(beg,end)。因为这在中间删除数据后会导致后面的数据向前移动,从而使效率低下。
与vector比:
1-高效的首段插入/删除,2-内存管理
deque的中find自定义的类型
以调用find()在deque中查找:
对应自定义的类和结构须添加:
booloperator == (const MyClass &other) const 成员函数;
或booloperator ==(const MyClass &one, const MyClass &another)全局函数。内存泄露
如果容器中含有元素:
则程序退出前须清空调用deque的clear()或~deque(),否则出现内存泄露。
如存储的是指针类型deque<MyClass*>:
每个指针对应一个堆内存。
1-则需要使用遍历每一个元素并调用delete *iterator;来释放指针指向内存。
2-然后在清空容器(deque的clear()或~deque())
- 《STL源码剖析》阅读笔记1
- 《STL源码剖析》阅读笔记
- 《STL源码剖析》---stl_deque.h阅读笔记(1)
- 《STL源码剖析》---stl_construct.h阅读笔记
- 《STL源码剖析》---stl_alloc.h阅读笔记
- 《STL源码剖析》---stl_uninitialized阅读笔记
- 《STL源码剖析》---stl_iterator.h阅读笔记
- 《STL源码剖析》---stl_vector.h阅读笔记
- 《STL源码剖析》---stl_list.h阅读笔记
- 《STL源码剖析》---stl_stack.h阅读笔记
- 《STL源码剖析》---stl_heap.h阅读笔记
- 《STL源码剖析》---stl_slist.h阅读笔记
- 《STL源码剖析》---stl_tree.h阅读笔记
- 《STL源码剖析》---stl_set.h阅读笔记
- 《STL源码剖析》---stl_map.h阅读笔记
- 《STL源码剖析》---stl_multiset.h阅读笔记
- 《STL源码剖析》---stl_pair.h阅读笔记
- 《STL源码剖析》---stl_multimap.h阅读笔记
- 获得网卡MAC地址
- BaseAdapter 自定义适配器设置网格布局
- UML—对象图
- Makefile学习笔记
- Win7下安装ZendStdio5.5.1(安装+汉化)
- 《STL源码剖析》阅读笔记1
- 双链表
- Vim初学 - 在Redhat Linux 9中编译和配置gvim 7.0
- Physics.Raycast中的层级
- Mac-safari查看网页源代码
- 哈希表
- Linux下使用C/C++访问数据库——Oracle之OCI篇
- jquery $.fn $.fx是什么意思
- 怒!!!