C++ Primer第五版学习 第十章

泛型算法为什么叫泛型

可以运用在多种容器类型之上,而容器内的元素类型也可以多样化。

标准库算法对迭代器而不是容器进行操作。因此,算法不能直接添加或删除元素。

find(iter1, iter2, value)搜索算法。前两个参数是迭代器表示范围,第三个参数是一个值。返回指向第一个等于给定值的元素的迭代器。
count(iter1, iter2, value)计数算法。前两个参数是迭代器表示范围,第三个参数是一个值。返回给定值value在序列中出现的次数。
accumulate(begin, end, init)求和算法。前两个参数指出了需要求和的元素的范围,第三个参数是和的初值。
equal(it1.begin, it1.end, it2.begin)

确定两个序列是否保存相同的值,返回bool值。

三个参数都是迭代器,前两个表示第一个序列中的范围,第三个表示第二个序列的首元素。(基于一个非常重要的假设才成立,第二个序列至少和第一个序列一样长)

fill(begin, end, value)向给定输入序列中写入数据。前两个参数是指定范围的迭代器,第三个参数是给定的写入值
fill_n(begin, size, value)将给定值赋予迭代器指向的元素开始的指定个元素。接受一个迭代器、一个计数值、一个值。(要能够容纳)
back_inserter接受一个指向容器的引用,返回一个与该容器绑定的插入迭代器。当我们使用此迭代器赋值时,赋值运算符会调用push_back将一个具有给定值的元素添加到容器中
copy(iter1.begin, iter1.end, iter2)拷贝算法。接受三个迭代器,前两个表示一个输入范围,第三个表示目的序列的起始位置。(也要注意接收容器的容量)
replace(begin, end, value, revalue)替换算法,前两个是迭代器表示搜索范围,第三个参数表示搜索的值,第四个表示替换值
sort(begin, end, index)排序算法。前两个参数表示排序范围,第三个参数表示排序条件,默认升序。
unique(begin, end)重排输入范围,使所有元素都只出现一次,重复元素排列在尾部,返回指向不重复区域之后一个位置的迭代器。
erase(begin, end)删除给定范围内的元素
stable_sort(begin, end, index)排序,但是可以维持相等元素的原有顺序,(index可以是函数)
find_if(lter1, iter2, lambda)返回一个指向被找到对象的迭代器,如果没有找到对象,会返回这个 序列的结束迭代器。第三个参数是一个 lambda 表达式的谓词。这个 lambda 表达式以值的方式捕获 value,并在 lambda 参数大于 value 时返回 true。
find_each(iter1, iter2, lambda)接受迭代器内的对象,根据lambda中的操作对对象范围中的每一个元素进行操作

定制操作(向算法传递参数、函数)

 以sort为例

bool isShorter(const string &s1, const string &s2)
{
    return s1.size()<s2.size();
}

sort(words.begin(), words.end(), isShorter)
//按照长度由短至长排序

lambda表达式

C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。

只在一两个地方使用的简单操作,lambda表达式是最有用的。(如果一个操作需要很多语句才能完成,那么使用函数更好)
Lambda 的语法形式如下:

[函数对象参数(捕获列表)] (操作符重载函数参数) mutable 或 exception 声明 -> 返回值类型 {函数体}

//如:
[sz](const string &a)    {return a.size() >= sz;};

[]{return 1;};

我们可以忽略参数列表和返回类型,但是必须永远包含捕获列表和函数体。

lambda捕获列表

捕获列表解释
[]空捕获列表。lambda不能使用所在函数中的变量。一个lambda只有在捕获变量后才能使用它们。
[names]names是一个逗号分隔的名字列表,这些名字都是在lambda所在函数的局部变量,捕获列表中的变量都被拷贝,名字前如果使用了&,则采用引用捕获方式。
[&]隐式捕获列表,采用引用捕获方式。lambda体中所使用的来自所在函数的实体都采用引用方式使用。
[=]隐式捕获列表,采用值捕获方式。
[&, identifier_list]identifier_list是一个逗号分隔的列表,包含0个或多个来自所在函数的变量。这些变量采用值捕获方式,而任何隐式捕获的变量都采用引用方式捕获。identifier_list中的名字前面不能使用&
[=, identifier_list]identifier_list中的变量采用引用方式捕获,而任何隐式捕获的变量都采用值方式捕获。identifier_list中的名字不能包括this,且前面必须使用&

参数绑定

标准库bind函数(没看懂,可以去搜搜资料看看例子)

C++11 bind函数_青山绿水-CSDN博客_c++bindbind函数的使用详解可以将bind函数看作是一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。调用bind的一般形式:auto newCallable = bind(callable,arg_list);`其中,newCallable本身是一个可调用对象,arg_list是一个逗号分隔的参数列表,对应给定的callable的参数。即,当我们调用n...https://blog.csdn.net/qq_35721743/article/details/83308765

迭代器再探

插入迭代器这些迭代器被绑定到一个容器上,可用来向容器插入元素
流迭代器这些迭代器被绑定到输入或输出流上,可用来遍历所有关联的IO流
反向迭代器这些迭代器向后而不是向前移动。除了forward_list之外的容器都有反向迭代器
移动迭代器即移动其中的元素

插入迭代器

back_inserter创建一个使用push_back的迭代器
front_inserter创建一个使用push_front的迭代器
inserter创建一个使用insert的迭代器。此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器。元素将被插入到给定迭代器所表示的元素之前

iostream迭代器

istream_iterator操作
istream_iterator<T>  in( is );in从输入流is读取类型为T的值
istream_iterator<T> end;读取类型为T 的值的istream_iterator迭代器,表示尾后位置

in1 == in2

in1 != in2

in1 和in2必须读取相同类型,如果它们都是尾后迭代器,或绑定到相同的输入,则两者相同
*in返回从流中读取的值
in->mem与(*in).mem的含义相同
++in,in++返回元素类型所定义的>>运算符从输入流中读取下一个值
ostream_iterator操作
ostream_iterator<T> out (os)out将类型为T的值写到输出流os中
ostream_iterator<T> out (os, d) out将类型为T的值写到输出流os中,每个值后面都输出一个d,d指向一个空字符结尾的字符数组
out = val用<<运算符将val写入到out所绑定的ostream中。val的类型必须与out可写的类型兼容
*out、++oout、out++这些运算符是存在的,但不对out做任何事情,每个运算符都返回out

反向迭代器

即在容器中从尾元素向首元素反向移动的迭代器。

对于反向迭代器,递增(以及递减)操作的含义会颠倒过来。

递增一个反向迭代器会移动到前一个元素,递减一个迭代器会移动到下一个元素。

不能在forward_list或一个流迭代器创建反向迭代器。

算法形参模式

alg (beg, end, other parms);

alg (beg, end, dest, other parms);

alg (beg, end, beg2, other parms);

alg (beg, end, beg2, end2, other parms);

其中,alg 是算法的名字,beg 和 end 指定算法操作的元素范围。我们通常将该范围称为算法的“输入范围”。

带有单个目标迭代器的算法:dest 形参是一个迭代器,用于指定存储输出数据的目标对象。

带第二个输入序列的算法:有一些算法带有一个 beg2 迭代器形参,或者同时带有 beg2 和 end2 迭代器形参,来指定它的第二个输入范围。带有 beg2 而不带 end2 的算法将 beg2 视为第二个输入范围的首元素,但没有指定该范围的最后一个元素。这些算法假定以 beg2 开始的范围至少与 beg和 end 指定的范围一样大。

特定容器算法

list 和 forward_list成员函数版本的算法(以下均返回void)

lst.merge(lst2);

lst.merge(lst2, comp);

将来自lst2的元素合并入lst。lst和lst2都必须是有序的。元素将从lst2中删除。在合并之后,lst2变为空。

lst.remove(val);

lst.remove_if(pred);

调用erase删除掉与给定值相等(==)或令一元谓词为真的每个元素
lst.reverse()反转lst中元素的顺序

lst.sort();

lst.sort(comp);

使用<或给定比较操作排序元素

lst.unique();

lst.unique(pred)

调用erase删除同一个值的连续拷贝,第一个版本使用==;第二个版本使用给定的二元谓词

链表类型还定义了splice算法(特有)

lst.splice(args)

flst.splice_after(args)

参数形式:

(p, lst2)

p是一个指向lst中元素的迭代器,或一个指向flst首前位置的迭代器。函数将lst2的所有元素移动到lst中p之前的位置或是flst中p之后的位置,将元素从lst中删除。lst2与lst的类型必须相同,且不能是同一个链表

(p, lst2, p2)

p2是指向lst2中位置的有效的迭代器。将p2指向的元素移动到lst中,或将p2之后的元素移动到flst中。lst2可以是与lst或flst相同的链表

(p, lst2, b, e)b和e必须表示lst2中的合法范围,将给定范围中的元素从lst2移动到lst或flst。lst2与lst(flst)可以是相同的链表,但p不能指向给定范围内的元素

        

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值