C++泛型算法1——初识泛型算法

本文介绍了C++泛型算法,它实现经典算法公共接口,可用于不同元素和容器类型。算法通过迭代器操作元素范围,不依赖容器但依赖元素类型操作,且不会改变容器大小。文中还介绍了只读、写元素、重排元素等算法,以及插入器和拷贝算法的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是泛型算法

顺序容器只定义了很少的操作:在多数情况下,我们可以添加和删除元素、访问首尾元素、确定容器是否为空以及获得指向首元素或尾元素之后位置的迭代器。

我们可以想象用户可能还希望做其他很多有用的操作:查找特定元素、替换或删除一个特定值、重排元素顺序等。

标准库并未给每个容器都定义成员函数来实现这些操作,而是定义了一组泛型算法(generic algorithm):

  1. 称它们为“算法”,是因为它们实现了一些经典算法的公共接口,如排序和搜索;
  2. 称它们是“泛型的”,是因为它们可以用于不同类型的元素和多种容器类型(不仅包括标准库类型,如vector或1ist,还包括内置的数组类型),以及我们将看到的,还能用于其他类型的序列。

概述

大多数算法都定义在头文件algorithm 中。标准库还在头文件 numeric中定义了以组数值泛型算法。

一般情况下,这些算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围来进行操作。

通常情况下,算法遍历范围,对其中每个元素进行一些处理。

例如,假定我们有一个int的vector,希望知道vector中是否包含一个特定值。回答这个问题最方便的方法是调用标准库算法 find:

	int val = 42;//我们将查找的值
		//如果在vec中找到想要的元素,则返回结果指向它,否则返回结果为vec.cend()
		auto result = find(vec.cbegin(), vec.cend(), val);
	//报告结果
	cout << "The value " << val
		<< (result == vec.cend()?" is not present" :" is present") << endl;

传递给find的前两个参数是表示元素范围的迭代器,第三个参数是一个值。

find将范围中每个元素与给定值进行比较。

它返回指向第一个等于给定值的元素的迭代器。

如果范围中无匹配元素,则find返回第二个参数来表示搜索失败。因此,我们可以通过比较返回值和第二个参数来判断拽索是否成功。

我们在输出语句中执行这个检测,其中使用了条件运算符来报告搜索是否成功。

由于find操作的是迭代器,因此我们可以用同样的find函数在任何容器中查找值。

例如,可以用find在一个string的list中查找一个给定值:

string val="a value";//我们要查找的值
// 此调用在list中查找string元素
auto result = find(1st,cbegin(), lst.cend(), val);

类似的,由于指针就像内置数组上的迭代器一样,我们可以用find在数组中查找值;

int ia[] ={27,210, 12,47,109,83};
int val = 83;
int* result = find(begin(ia),end(ia),val);

此例中我们使用了标准库begin和end函数来获得指向ia中首元素和尾元素之后位置的指针,并传递给find。

还可以在序列的子范围中查找,只需将指向子范围首元素和尾元素之后位置的迭代器(指针)传递给find。

例如,下面的语句在ia[1]、ia[2]和ia[3]中查找给定元素:

//在从ia[1]开始,直至(但不包含)ia[4]的范围内查找元素
auto result = find(ia + 1, ia + 4, val);

算法如何工作

为了弄清这些算法如何用于不同类型的容器,让我们更近地观察一下 find。find
的工作是在一个未排序的元素序列中查找一个特定元素。概念上,find应执行如下步骤:

  1. 访问序列中的首元素。
  2. 比较此元素与我们要查找的值。
  3. 如果此元素与我们要查找的值匹配,find返回标识此元素的值。
  4. 否则,find前进到下一个元素,重复执行步骤2和3。
  5. 如果到达序列尾,find应停止。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值