开发成长之路(5)-- C++从入门到开发(C++知名库:STL入门·算法

  • 其他

从find函数的转变看算法的泛化过程


让我们来手写一个find函数,我们的第一反应是:

int find(int arrayHead,int arraySize,int value){

for(int i = 0;i<arraySize;i++)

if(arrayHead[i] == value)

break;

return &(arrayHead[i])

}

但是呢,这样有越界的风险。

于是乎,我们进行一波的修改:

int *find(int *begin,int *end,int value){

while(begin!=end && *begin!=value)

++begin;

return begin;

}


接下来,我们对它进行泛化

template

T *find(T *begin,T *end,const T& value){

//传递数值由按值传递变为按地址传递,这样可以避免对象一大,传递成本的上升

while(begin!=end && *begin!=value)

++begin;

return begin;

}


接下来,上迭代器:

template<class Iterator,class T>

Iterator find(Iterator bedin,Iterator end,const T& value){

while(begin!=end && *begin!=value)

++begin;

return begin;

}

这便是一个完全泛化的find()函数,你可以在任何C++的标准库的某个头文件里看到它。


copy


讲到STL的算法,就不得不讲copy算法。由于copy算法简直是贯穿了整套STL体系,所以对于这个算法的优化做出的努力不可谓不多。

在这里插入图片描述

copy算法可以将输入区间[first,last]内的元素复制到输出区间[result,result+(last-first)内]。

在这里插入图片描述

如果输入输出区间完全没有重叠,当然毫无问题,否则便需特别注意。

如果输出区间的起点位于输入区间内,copy算法便(可能)会在输入区间的(某些)元素尚未被复制之前,就覆盖其值,导致错误结果。

如果copy根据其所接收的迭代器的特性决定调用memmove()来执行任务,就不会造成上述错误,因为memmove()会先将整个输入区间的内容复制下来,没有被覆盖的危险。

算法内容过于庞大,而且底层。


set_union(取两个集合的并集)


在这里插入图片描述


STL常用函数大集合

=====================================================================

vector 部分


#include

vector v1 = v2; //深拷贝构造

vector v1 = {0,1,2,3}; //initializer_list初始化

vector v1(v2.begin(), v2.end()); //vector或array初始化

vector v1(7); //初始化有7个元素的vector

vector v1(7, 3) //初始化有7个3的vector

vector v1(r, vector(c, 0)) //初始化r行c列全为0的矩阵

v1.clear(); //清空

v1.size(); //返回元素数量

v1.empty(); //是否为空

v1.front(); //访问第一个元素

v1.back(); //访问最后一个元素

v1.push_back(100); //末尾插入元素

v1.pop_back(); //清除末尾元素

iter = v1.insert(v1.begin(), 100); //在vector最前面插入100

iter = v1.insert(v1.begin(), v2.begin(), v2.end()); //插入另一个数组

iter = v1.erase(v1.begin()+2); //erase一个数

iter = v1.erase(v1.begin()+2, v1.begin()+5); //erase一个区间


list部分


list l1 = l2; //深拷贝构造

list l1 = {0,1,2,3}; //initializer_list初始化

list l1(l2.begin(), l2.end());

list l1(7); //初始化有7个元素的list

list l1(7, 3) //初始化有7个3的list

l1.clear(); //清空

l1.size(); //返回元素数量

l1.empty(); //是否为空

l1.front(); //访问第一个元素

l1.back(); //访问最后一个元素

l1.push_back(100); //末尾插入元素

l1.pop_back(); //清除末尾元素

iter = l1.insert(l1.begin(), 100); //在list最前面插入100

iter = l1.insert(l1.begin(), l2.begin(), l2.end()); //插入另一个数组

iter = l1.erase(l1.begin()+2); //erase一个数

iter = l1.erase(l1.begin()+2, l1.begin()+5); //erase一个区间


map/multimap


#include

map<int, string> m1 = {{2015, “Tom”}, {2016, “Jim”}}; //构造函数

m1.clear(); //清空

m1.size(); //返回元素数量

m1.empty(); //是否为空

m1.at[2015] = “Tom”; //取值,会检查key是否存在

m1[2015] = “Tom”; //若key存在则修改value,若不存在则创建

m1.count(key); //返回相应key的count,可以用于判断map中是否存在该key

iter = m1.find(key); //返回指向key的迭代器,用"!=m1.end()"判断是否找到

m1.lower_bound(key); //返回指向首个不小于key的迭代器

m1.upper_bound(key); //返回指向首个大于key的迭代器

m1.insert(make_pair(2015, “Tom”)); //使用pair插入

m1.insert
(pair<int, string>(2015, “Tom”));

m1.insert({2015, “Tom”}); //initializer_list插入

m1.erase(key); //返回被移除的元素的数量

m1.erase(iter); //清除iter指向的元素

m1.erase(m1.begin()+2, m1.begin()+5); //清除某个区间


set/multiset


//基于红黑树实现,有自动排序,插入O(logn),查找O(logn),删除O(logn)

#include

#include

set<int, less> c1(c2); //深拷贝构造

set<int, less> c1(c2.begin(), c2.end());

set<int, less> c1(c2.begin(), c2.end(), comp); //迭代器返回的元素依次排序

c1.clear(); //清空

c1.size(); //返回元素数量

c1.empty(); //是否为空

c1.count(elem); //返回elem的count,可以用于判断set中是否有elem

c1.find(elem); //返回指向elem的迭代器,用"!=c1.end()"判断是否找到

c1.lower_bound(elem); //返回指向首个不小于elem的迭代器

c1.upper_bound(elem); //返回指向首个大于elem的迭代器

c1.insert(elem); //插入单个elem

c1.insert(c2.begin(), c2.end()); //插入另一个set的某个区间

c1.erase(elem); //返回被移除的元素的数量

c1.erase(iter); //清除iter指向的元素

c1.erase(c1.begin()+2, c1.begin()+5); //清除某个区间


unordered_set/unordered_multiset


//基于哈希表实现,插入O(n),查找O(n),删除O(n)

//代价占用内存比set/multiset略大一点点,内部元素不排序

#include <unordered_set>

//大部分函数同set/multiset

//由于内部元素不排序,不能使用lower_bound和upper_bound

unordered_map/unordered_multimap


//基于哈希表实现,插入O(n),查找O(n),删除O(n)

//代价占用内存比map/multimap略大一点点,内部元素不排序

#include <unordered_map>

  • 22
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值