STL usage

简介
STL (Standard Template Library)为C++程序库,容纳于C++标准库中。包含很多常用的数据结构和基本算法。

  1. STL特点之一:数据结构和算法分离。
  2. 不是OOP的,主要依赖于模板和内联函数的使用而不是封装、继承或者虚函数。
  3. STL体现了泛型化程序设计的思想,引入了很多新名词:需求、概念、模型、容器、算法、迭代子等。泛型和多态一样是一种软件的复用技术。

学习入口

1. STL内容

STL中六大组件

  1. 容器:为一种数据结构,如list、vector、deques,以类模板方法提供,为了访问容器中的数据,可以使用容器类输出的迭代器。
  2. 迭代器:提供了访问容器中对象的方法。如:可以使用迭代器指定list或者vector中一定范围的对象。迭代器就如同指针。
  3. 算法:用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用。
  4. 仿函数
  5. 适配器
  6. 分配器

1.1 容器

STL中的容器有队列容器、关联容器、容器适配器、位集、串包等。容器类自动申请和释放内存,无需new和delete操作。

1.1.1 序列式容器

每个元素都有固定位置,取决于插入顺序,vector、deque、list。
Vector: 将元素置于动态数组中管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时。
Deque: (double-ended queue)可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时。
List: 双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针。

1.1.2 关联式容器

元素位置取决于特定的排序准则,和插入顺序无关,set、multiset、map、multimap等。
Set/Multiset:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找。
Map/Multimap:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找。


1.2 迭代器

用于提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来,重载了*,++,==,!=,=运算符。用以操作复杂的数据结构,容器提供迭代器,算法使用迭代器;常见的一些迭代器类型:iteratorconst_iteratorreverse_iteratorconst_reverse_iterator


1.3 算法

STL提供了大约100个实现算法的模版函数,比如算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以你所指定的规则对序列进行稳定性排序等等。
只要我们熟悉了STL之后,许多代码可以被大大的化简,只需要通过调用一两个算法模板,就可以完成所需要的功能并大大地提升效率。
算法部分主要由头文件<algorithm><numeric><functional>组成。
1.3.1. <algorithm>是所有STL头文件中最大的一个(尽管它很好理解),它是由一大堆模版函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。
1.3.2. <numeric>体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。
1.3.3. <functional>中则定义了一些模板类,用以声明函数对象。

STL中的算法大致分为四类:

  • 非可变序列算法:指不直接修改其所操作的容器内容的算法。
  • 可变序列算法:指可以修改它们所操作的容器内容的算法。
  • 排序算法:对序列进行排序和合并的算法、搜索算法以及有序序列上的集合操作。
  • 数值算法:对容器内容进行数值计算。

STL所有算法介绍:

  • 查找算法13个,判断容器中是否包含某个值。

adjacent_find: 在iterator对标识元素范围内,查找一对相邻重复元素,找到则返回指向这对元素的第一个元素的 ForwardIterator。否则返回last。重载版本使用输入的二元操作符代替相等的判断。
binary_search: 在有序序列中查找value,找到返回true。重载的版本实用指定的比较函数对象或函数指针来判断相等。
count: 利用等于操作符,把标志范围内的元素与输入值比较,返回相等元素个数。
count_if: 利用输入的操作符,对标志范围内的元素进行操作,返回结果为true的个数。
equal_range: 功能类似equal,返回一对iterator,第一个表示lower_bound,第二个表示upper_bound。
find: 利用底层元素的等于操作符,对指定范围内的元素与输入值进行比较。当匹配时,结束搜索,返回该元素的 一个InputIterator。
find_end: 在指定范围内查找"由输入的另外一对iterator标志的第二个序列"的最后一次出现。找到则返回最后一对的第一 个ForwardIterator,否则返回输入的"另外一对"的第一个ForwardIterator。重载版本使用用户输入的操作符代 替等于操作。
find_first_of: 在指定范围内查找"由输入的另外一对iterator标志的第二个序列"中任意一个元素的第一次出现。重载版本中使 用了用户自定义操作符。
find_if: 使用输入的函数代替等于操作符执行find。
lower_bound: 返回一个ForwardIterator,指向在有序序列范围内的可以插入指定值而不破坏容器顺序的第一个位置。重载函 数使用自定义比较操作。
upper_bound: 返回一个ForwardIterator,指向在有序序列范围内插入value而不破坏容器顺序的最后一个位置,该位置标志 一个大于value的值。重载函数使用自定义比较操作。
search: 给出两个范围,返回一个ForwardIterator,查找成功指向第一个范围内第一次出现子序列(第二个范围)的位 置,查找失败指向last1。重载版本使用自定义的比较操作。
search_n: 在指定范围内查找val出现n次的子序列。重载版本使用自定义的比较操作。

  • 排序和通用算法14个:提供元素排序策略

inplace_merge: 合并两个有序序列,结果序列覆盖两端范围。重载版本使用输入的操作进行排序。
merge: 合并两个有序序列,存放到另一个序列。重载版本使用自定义的比较。
nth_element: 将范围内的序列重新排序,使所有小于第n个元素的元素都出现在它前面,而大于它的都出现在后面。重 载版本使用自定义的比较操作。
partial_sort: 对序列做部分排序,被排序元素个数正好可以被放到范围内。重载版本使用自定义的比较操作。
partial_sort_copy: 与partial_sort类似,不过将经过排序的序列复制到另一个容器。
partition: 对指定范围内元素重新排序,使用输入的函数,把结果为true的元素放在结果为false的元素之前。
random_shuffle: 对指定范围内的元素随机调整次序。重载版本输入一个随机数产生操作。
reverse: 将指定范围内元素重新反序排序。
reverse_copy: 与reverse类似,不过将结果写入另一个容器。
rotate: 将指定范围内元素移到容器末尾,由middle指向的元素成为容器第一个元素。
rotate_copy: 与rotate类似,不过将结果写入另一个容器。
sort: 以升序重新排列指定范围内的元素。重载版本使用自定义的比较操作。
stable_sort: 与sort类似,不过保留相等元素之间的顺序关系。
stable_partition: 与partition类似,不过不保证保留容器中的相对顺序。

  • 删除和替换算法15个

copy: 复制序列
copy_backward: 与copy相同,不过元素是以相反顺序被拷贝。
iter_swap: 交换两个ForwardIterator的值。
remove: 删除指定范围内所有等于指定元素的元素。注意,该函数不是真正删除函数。内置函数不适合使用remove和 remove_if函数。
remove_copy: 将所有不匹配元素复制到一个制定容器,返回OutputIterator指向被拷贝的末元素的下一个位置。
remove_if: 删除指定范围内输入操作结果为true的所有元素。
remove_copy_if: 将所有不匹配元素拷贝到一个指定容器。
replace: 将指定范围内所有等于vold的元素都用vnew代替。
replace_copy: 与replace类似,不过将结果写入另一个容器。
replace_if: 将指定范围内所有操作结果为true的元素用新值代替。
replace_copy_if: 与replace_if,不过将结果写入另一个容器。
swap: 交换存储在两个对象中的值。
swap_range: 将指定范围内的元素与另一个序列元素值进行交换。
unique: 清除序列中重复元素,和remove类似,它也不能真正删除元素。重载版本使用自定义比较操作。
unique_copy: 与unique类似,不过把结果输出到另一个容器。

  • 排列组合算法2个提供计算集合按一定顺序的所有可能排列组合。

next_permutation: 取出当前范围内的排列,并重新排序为下一个排列。重载版本使用自定义的比较操作。
prev_permutation: 取出指定范围内的序列并将它重新排序为上一个序列。如果不存在上一个序列则返回false。重载版本使用自定义的比较操作。

  • 算术算法4个

accumulate: iterator对标识的序列段元素之和,加到一个由val指定的初始值上。重载版本不再做加法,而是传进来的 二元操作符被应用到元素上。
partial_sum: 创建一个新序列,其中每个元素值代表指定范围内该位置前所有元素之和。重载版本使用自定义操作代 替加法。
inner_product: 对两个序列做内积(对应元素相乘,再求和)并将内积加到一个输入的初始值上。重载版本使用用户定义 的操作。
adjacent_difference: 创建一个新序列,新序列中每个新值代表当前元素与上一个元素的差。重载版本用指定二元操作计算相 邻元素的差。

  • 生成和异变算法(6个)

fill: 将输入值赋给标志范围内的所有元素。
fill_n: 将输入值赋给first到first+n范围内的所有元素。
for_each: 用指定函数依次对指定范围内所有元素进行迭代访问,返回所指定的函数类型。该函数不得修改序列中的元素。
generate: 连续调用输入的函数来填充指定的范围。
generate_n: 与generate函数类似,填充从指定iterator开始的n个元素。
transform: 将输入的操作作用与指定范围内的每个元素,并产生一个新的序列。重载版本将操作作用在一对元素上,另外一 个元素来自输入的另外一个序列。结果输出到指定容器。

  • 关系算法(8个)

equal: 如果两个序列在标志范围内元素都相等,返回true。重载版本使用输入的操作符代替默认的等于操 作符。
includes: 判断第一个指定范围内的所有元素是否都被第二个范围包含,使用底层元素的<操作符,成功返回 true。重载版本使用用户输入的函数。
lexicographical_compare: 比较两个序列。重载版本使用用户自定义比较操作。
max: 返回两个元素中较大一个。重载版本使用自定义比较操作。
max_element: 返回一个ForwardIterator,指出序列中最大的元素。重载版本使用自定义比较操作。
min: 返回两个元素中较小一个。重载版本使用自定义比较操作。
min_element: 返回一个ForwardIterator,指出序列中最小的元素。重载版本使用自定义比较操作。
mismatch: 并行比较两个序列,指出第一个不匹配的位置,返回一对iterator,标志第一个不匹配元素位置。 如果都匹配,返回每个容器的last。重载版本使用自定义的比较操作。

  • 集合算法(4个)

set_union: 构造一个有序序列,包含两个序列中所有的不重复元素。重载版本使用自定义的比较操作。
set_intersection: 构造一个有序序列,其中元素在两个序列中都存在。重载版本使用自定义的比较操作。
set_difference: 构造一个有序序列,该序列仅保留第一个序列中存在的而第二个中不存在的元素。重载版本使用 自定义的比较操作。
set_symmetric_difference: 构造一个有序序列,该序列取两个序列的对称差集(并集-交集)。

  • 堆算法(4个)

make_heap: 把指定范围内的元素生成一个堆。重载版本使用自定义比较操作。
pop_heap: 并不真正把最大元素从堆中弹出,而是重新排序堆。它把first和last-1交换,然后重新生成一个堆。可使用容器的 back来访问被"弹出"的元素或者使用pop_back进行真正的删除。重载版本使用自定义的比较操作。
push_heap: 假设first到last-1是一个有效堆,要被加入到堆的元素存放在位置last-1,重新生成堆。在指向该函数前,必须先把 元素插入容器后。重载版本使用指定的比较操作。
sort_heap: 对指定范围内的序列重新排序,它假设该序列是个有序堆。重载版本使用自定义比较操作。

1.4 仿函数

1.4.1 概述

仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了。
  有些功能的的代码,会在不同的成员函数中用到,想复用这些代码。
1)公共的函数,可以,这是一个解决方法,不过函数用到的一些变量,就可能成为公共的全局变量,再说为了复用这么一片代码,就要单立出一个函数,也不是很好维护。
2)仿函数,写一个简单类,除了那些维护一个类的成员函数外,就只是实现一个operator(),在类实例化时,就将要用的,非参数的元素传入类中。

1.4.2 仿函数(functor)在编程语言中的应用

1)C语言使用函数指针和回调函数来实现仿函数,例如一个用来排序的函数可以这样使用仿函数。

#include <stdio.h>
#include <stdlib.h>
//int sort_function( const void *a, const void *b);
int sort_function( const void *a, const void *b)
{   
	return *(int*)a-*(int*)b;
}
 
int main()
{
   
   int list[5] = { 54, 21, 11, 67, 22 };
   qsort((void *)list, 5, sizeof(list[0]), sort_function);//起始地址,个数,元素大小,回调函数 
   int  x;
   for (x = 0; x < 5; x++)
		  printf("%i\n", list[x]);
			      
   return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: STL(Standard Template Library)算法是C++标准库中的一组通用算法,用于处理各种类型的数据结构。STL算法提供了一系列函数对象和迭代器,以便能够对容器中的元素进行常见的操作,如查找、排序、删除、替换等。 STL算法主要分为以下几类: 1. 非修改性算法:这类算法不会改变容器中的元素,例如查找、计数、比较等。常用的函数包括find、count、equal等。 2. 修改性算法:这类算法会修改容器中的元素,例如排序、删除、替换等。常用的函数包括sort、remove、replace等。 3. 排序算法:STL提供了多种排序算法,如快速排序、归并排序等。常用的函数包括sort、stable_sort等。 4. 数值算法:这类算法主要用于数值计算,如求和、积累、内积等。常用的函数包括accumulate、inner_product等。 5. 集合操作:这类算法主要用于集合的操作,如交集、并集、差集等。常用的函数包括set_intersection、set_union等。 STL算法的优势在于其通用性和高效性。通过使用STL算法,我们可以在不同类型的容器上进行相同的操作,避免了针对不同容器实现不同操作的麻烦。此外,STL算法的底层实现经过优化,通常比手动编写的算法更高效。 总之,STL算法是C++标准库中提供的一组通用算法,用于处理各种类型的数据结构。通过使用STL算法,我们可以方便地对容器进行各种操作,提高开发效率并保证程序的高效性。 ### 回答2: STL算法是C++标准模板库(Standard Template Library)中的一部分,它提供了丰富的算法操作,方便我们在处理数据时进行快速、高效的操作。 STL算法包含很多算法函数,比如排序(sort)、查找(find)、替换(replace)、去重(unique)、合并(merge)等等。这些算法函数可以处理各种数据容器,比如数组、容器、字符串等。 STL算法的使用非常方便,我们只需要包含<algorithm>头文件,并使用其中的函数即可。例如,我们可以使用sort函数对一个数组进行排序,使用find函数在容器中查找某个元素,使用replace函数替换容器中的某个值等等。 STL算法的好处是它提供了统一的接口和一致的命名规范,使得我们在处理不同的数据结构时都能使用相同的函数名来调用相应的操作。这样可以大大提高代码的复用性和可读性,减少了我们编写和维护代码的工作量。 此外,STL算法还可以通过函数对象(function object)、谓词(predicate)等机制来灵活地进行自定义操作。我们可以自定义比较函数来实现按照特定条件进行排序,或者自定义判断函数来在查找时指定特定的条件等。这样可以让我们的代码更加灵活和可扩展。 总之,STL算法是C++中非常重要和强大的一部分,它提供了丰富的算法函数,方便我们在处理数据时进行各种操作。它的使用简单方便,可以提高代码的复用性和可读性,是C++开发中不可或缺的工具之一。 ### 回答3: STL(Standard Template Library,标准模板库)是C++中的一个重要部分,其中的算法部分(Algorithm)是其核心。STL Algorithm提供了一组强大的算法,用于对各种容器(如数组、向量、列表等)中的元素进行各种操作和处理。 STL算法可以分为若干类别,其中包括常用算法、排序算法、查找算法、数值算法等等。常用算法如copy(复制)、find(查找)、transform(转换)等,它们可以快速且高效地完成各种常见的操作。排序算法如sort(排序)、stable_sort(稳定排序)等,可以根据指定的规则对容器中的元素进行排序。查找算法如binary_search(二分查找)和lower_bound(寻找下界)等,可以在有序容器中快速查找指定元素。数值算法如accumulate(累加)、partial_sum(部分求和)等,用于对数值进行处理和计算。 STL的优势在于其算法的可重用性和通用性。STL Algorithm是基于模板的设计,它可以适用于不同类型的容器和元素。无论是基本数据类型还是自定义类型,只要满足一定的要求(如支持迭代器),就可以使用STL算法对其进行操作。这种通用性使得STL Algorithm可以被广泛应用于各种场景,大大提高了开发效率。 总结来说,STL算法是C++中的一组强大工具,用于对各种容器中的元素进行各种操作和处理。它的通用性和可重用性使得开发者可以更加高效地完成各种任务,提高代码的可读性和可维护性。无论是在日常开发中还是在算法竞赛中,STL Algorithm都扮演着重要的角色。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gkbytes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值