GeekBand STL与泛型编程 Third Week

GeekBand STL与泛型编程 Third Week

变易算法

变易算法是指那些改变容器中对象的操作。具体包括:

  1. copy

    template<class _InIt, class _OutIt> inline
    _OutIt copy(_InIt _First, _InIt _Last, _OutIt _Desc)
    // 将对象从 [_First, _Last) 拷贝至 [), 其中:_DestLast = _Dest+(_Last - _First).此算法是按照顺序拷贝的: _First, _First+1,..., _Last -1
    // copy 可以实现将容器中的对象左移。
    
  2. swap

    template<class _Ty> inline
    void swap(_Ty& _Left, _Ty& _Right)
    // 交换对象 _Left 和 _Right
    
  3. transform

    template<class _InIt, class _OutIt, class _Fn1> inline 
    _OutIt transform(_InIt _First, _InIt _Last, _OutIt _Desc, _Fn1 _Func)
    // 对于 [_First1,_Last)中每个 it,应用 _Func(*it), 并且将执行结果放入_Dest指定的区间,即: *(_Desc+i) = _Func(*(_First+i)), 其中 0 ≤ i < _Last1 - _First1
    
  4. replace

    template<class _FwdIt, class _Ty> inline
    void replace(_FwdIt _First, _FwdIt _Last, const _Ty& _Oldval, const _Ty& _Newval)
    // 对于区间 [_First, _Last)中每个迭代器it,如果满足 : *it == _Oldval, 则执行: *it = _Newval
    
  5. fill

    template<class _FwdIt, class _Ty> inline
    void fill(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
    // 将 _Val赋值给 [_First, _Last) 中的每个元素
    
  6. generate

    template<class _FwdIt, class _Fn0> inline
    void generate(_FwdIt _First,_FwdIt _Last, _Fn0 _Func)
    // 将调用 _Func的结果赋值给 [_First, _Last)中每个元素
    
  7. remove

    template<class _FwdIt, class _Ty> inline
    _FwdIt remove(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
    // 将[_First, _Last)中所有等于 _Val的元素全部删除。也就是说,remove返回一个迭代器_Last2(_Last2≤_Last),使得[_First,_Last2)中没有与_Val相等的元素。
    
  8. unique

    template<class _FwdIt> inline
    _FwdIt unique(_FwdIt _First, _FwdIt _Last)
    // 从[_First, _Last)去除重复的元素(只保留一份),返回一个新的迭代器 _Last2, 使得 [_First, _Last2)中没有重复出现的元素
    
  9. reserve

    template<class _BidIt> inline
    void reverse(_BidIt _First, _BidIt _Last)
    // 对于 0 ≤ it ≤ (_Last - _First) /2 中的每个元素,做如下交换: *(_First+it) <- -> *(_Last - (it + 1))
    
  10. rotate

    template<class _FwdIt> inline
    _FwdIt rotate(_FwdIt _First, _FwdIt _Mid, _FwdIt _Last)
    // 交换区间 : [_First, _Mid) <- -> [_Mid, _Last)
    
  11. random_shuffle

    template<class _RanIt> inline
    void random_shuffle(_RanIt _First, _RandIt _Last) // 采用rand
    // 对区间[_First, _Last)中的元素进行洗牌。如果令 N=_Last-_First, 那么该算法即从 N! 的可能排列中随机选择一种
    
  12. partition

    template<class _FwdIt, class _Pr> inline
    _FwdIt partition(_FwdIt _First, _FwdIt _Last, _Pr -Pred)
    // 基于 _Pred 对容器中的元素进行划分,将区间[_First,_Last)划分成两部分, [_First, _Mid) 与 [_Mid, _Last),使得: 对于任意的 it1 ∈ [_Mid, _Last), _Pred(*it2) == false
    

排序

排序是算法中最基本和重要的算法。C++ STL 中提供了基本的 sort 算法。

相关算法接口如下:

  1. sort

    template<class _RanIt> inline 
    void sort(_RanIt _First, _RanIt _Last)
    // 对[_First, _Last) 中的元素进行排序
    // 对于被排序的元素,需要提供operator < 
    
  2. partial_sort

    template<class _RanIt> inline 
    void partial_sort(_RanIt _First, _RanIt _Mid, _RanIt _Last)
    // 对 [_First, _Last) 中的部分元素进行排序,使得 [_First, _Mid) 中的元素是有序的, 而[_Mid, _Last) 中的元素则是未定义的
    
  3. binary_search

    template<class _FwdIt, class _Ty> inline
    bool binary_search(_FwdIt _First, _FwdIt _Last, const _Ty& _Val)
    // 在 [_First, _Last)中查找等于 _Val 的元素
    // 容器中的元素首先要排序
    
  4. merge

    tempalte<class _InIt1, class _InIt2, class _OutIt> inline _OutIt merge(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2, _OutIt _Desc)
    // 将排好序的 [_First1, _Last1) 与 [_First2, _Last2) 合并到 _Dest
    
  5. includes

    tempalte<class _InIt1, class _InIt2> inline
    bool includes(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _InIt2 _Last2)
    // 判别[_First1, _Last1) 是否包含 [_First2, _Last2)
    // [_First1, _Last1) 和 [_First2, _Last2) 都是排好序的
    
  6. 基于堆的算法(Heap operations)

    make_heap
    push_heap
    pop_heap
    sort_heap
    

数值算法

泛型数值算法包含在 <numeric> 头文件中,包括:

  1. accumulate

    template<class _InIt, class _Ty> inline
    _Ty accumulate(_InIt _First, _InIt _Last, _Ty _Val)
    // 对[_First, _Last) 中的每个元素进行累加,具体操作为:设result=_Val, 对于每个 it ∈[_First, _Last), result += *it
    
    // 也可以自定义result的处理函数,不仅仅是 +=。
    template<class _InIt, class _Ty, class _Fn2> inline
    _Ty accumulate(_InIt _First, _InIt _Last, _Ty _Val, _Fn2 _Func)
    // 其中 result 的操作按照如下的操作进行。 result = _Func(*it, result)
    
  2. inner_product

    template<class _InIt1, class _InIt2, class _Ty> inline _Ty inner_product(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2, _Ty _Val)
    // 对 [_First1, _Last1) 和 [_First2, _Last2) 进行如下的操作, 设 result = _Val, 对于每个 it1 ∈[_First1, _Last1), result = result + (*it1) ✖️ *(_First2 + (it1 - _First1))
    
  3. partial_sum

    template<class _InIt, class _OutIt> inline _OutIt
    partial_sum(_InIt _First, _InIt _Last, _OutIt _Dest)
    //设 it=_First, *it = *_First, *(it+1)=*_First+*(_First+1), ..., 依此类推
    
  4. adjacent_difference

    template<class _InIt, class OutIt> inline
    _OutIt adjacent_difference(_InIt _First, _InIt _Last, _OutIt _Dest)
    // 设 *result=*_First, 对于每个 it ∈[_First +1, _Last), *it 与 *(it-1)的差赋值给 *(result+(it-_First)) 
    

内存分配器

每个STL的容器都会有一个内存分配器,负责管理容器的内存分配和回收。C++ 的 STL 容器默认都有一个内存分配器,一般情况下,我们是不需要自己实现allcator的,默认的内存分配器足够高效和稳定。

根据STL的规范,以下是allocator的必要接口 和 type 类型。

allocator::value_type

allocator::pointer

allocator::const_pointer

allocator::reference

allocator::const_reference

allocator::size_type

allocator::difference_type

allocator::rebind // 一个嵌套的 class template. class rebind<U> 拥有唯一成员 other,那么是一个typedef,代表 allocator<U>

allocator::allocator() // default construct

allocator::allocator(const allocator&) // copy constructor

template<class U>allocator::allocator(const allocator<U>&) // 泛化的 copy constructor

allocator::~allocator() // destructor

pointer allocator::address(reference x)const // 返回某个const对象的地址。算式 a.address(x) 等同于 &x.

const_pointer allocator::address(const_reference x)const // 返回某个const对象的地址

pointer allocator::allocate(size_type n,const void* = 0) // 分配空间,足以存储n个T对象,第二个参数是个提示,实现上可能会利用它来增进区域性,或完全忽略之

void allocator::deallocate(pointer p,size_type n) // 释放先前分配的空间

size_type allocator::max_size() const // 返回可成功分配的最大值

void allocator::construct(pointer p, const T& x) // 等同于 new ((void*) p) T(x)

void allocator::destroy(pointer p) // 等同于 p->~T()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容