C++之泛型算法

只读算法

(1)accumulate返回容器的和

int sum = accumulate(vec.cbegin(),vec.cend(),0);
string sum = accumulate(v.cbegin(),v.cend(),string(""));//注意第三个参数不接受"",因为const char*类型没有重载“+”会编译错误

(2)equal比较两个等长的容器(元素个数相同)是否保存相同的值

equal(vec1.cbegin(),vec1.cend(),vec2.cbegin());

写容器元素算法

(1)fill填充元素值

fill(vec.begin(),vec.end(),0);

(2)back_inserter接收一个容器的引用,返回该容器的插入迭代器,可以做插入容器操作

vector<int> vec;
auto it = back_inserter(vec);
*it = 42;  //vec中有42

vector<int> vec;
fill_n(back_inserter(vec),10,0); //添加10个元素到vec

(2)copy复制数组

int a1[] = {0,1,2,3,4,5,6};
int a2[sizeof(a1)/sizeof(*a1)];
auto ret = copy(begin(a1),end(a1),a2);

(3)replace将容器内指定值置换成另一个值

replace(vec.begin(),vec.end(),0,42);  //0换成42;

(4)replace_copy如果不想改变原数组可以使用这个,得到置换后的新数组

vector<int> newvec;
replace_copy(vec.begin(),vec.end(),back_inserter(newvec).0,42);

消除重复单词算法

void elimDups(vector<string>& words)
{
	sort(words.begin(),words.end());
	auto end_unique = unique(words.begin(),words.end());
	words.erase(end_unique,words.end());
}

lambda表达式

(1)标准写法
[capture list](parameter list) -> return type { function body}
我们可以忽略参数列表和返回类型,但是永远包含捕获列表和函数体

vector<int> vec;
sort(words.begin(),words.end(),[](const string& a,const string& b){return a.size()<b.size();}}

(2)捕获列表
捕获列表中的参数捕获该函数所在的局部变量,然后在lambda表达式中可以直接进行使用,而参数列表是外部调用的时候传入的参数。

//获取一个迭代器,指向第一个满足size()>=sz的元素
auto wc = find_if(words.begin(),words.end(),[sz](const string& a){return a.size() >= sz}};
//打印长度大于等于给定值的单词,每个单词后面接一个空格
for_each(wc,words.end(),[&os](const string& s){cout<<s<<"";});

(3)隐式捕获和显示捕获
当我们混合喜欢使用隐式捕获和显示捕获时,显示捕获的变量必须使用与隐式捕获不同的方式。即,如果隐式捕获是引用方式,则显示捕获命名变量必须采用值方式,因此不能在其名字前使用&。类似的,如果隐式捕获采用的是值方式,则显示捕获命名变量必须。
(4)可变mutable
默认情况下,对应一个值被拷贝的变量,lambda不会改变其值。如果我们希望能改变一个被捕获的变量的值,就必须在参数列表首加上关键字mutable。因此,可变lambda能省略参数列表:

void fcn3()
{
	size_t v1 = 42;
	auto f = [v1]()mutable{ return ++v1};
	v1 = 0;
	auto j = f();  //j = 43;
}

(5)指定lambda返回类型
首先给出一个例子,使用transform算法对容器内所有元素取绝对值

transform(vec.begin(),vec.end(),vec.begin(),[](int i){return i<0 ? -i : i;});

如果修改成如下格式

transform(vec.begin(),vec.end(),vec.begin(),[](int i){if(i<0) return -i else return i;});

发现编译器过不去。是因为,默认情况下,如果一个lambda体包含return之外的任何语句,则编译器假定此lambda返回void,所以我们要指定返回类型

transform(vec.begin(),vec.end(),vec.begin(),[](int i)->int{if(i<0) return -i else return i;});

(6)bind函数
使用bind函数可以解决函数参数不对应的问题,下面是使用bind重排参数顺序的实例

using namespace std::placeholders;
sort(vec.begin(),vec.end(),cmp);
sort(vec.begin(),vec.end(),bind(cmp,_2,_1));  //颠倒参数传递

使用引用传递bind

for_each(vec.begin(),vec.end(),bind(print,ref(os),_1,' '));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值