非变异算法不直接改变其操作的数据结构的元素,其查找数据结构中的元素,检查序列元素是否满足某函数式,计算序列元素满足某条件的个数等。下表是按功能划分的非变异算法
1.循环 for_each 遍历容器元素,对每个元素执行相同的函数操作
2.查询 find 在单迭代器序列中找出某个值第一次出现的位置
find_if 在单迭代器序列中找出符合某谓词的第一个元素
find_first_of 在双迭代器序列中找出子序列中某元素第一次出现的位置
adjacent_find 在单选代器序列中找出第一次相邻值相等元素的位置
find_end 在双迭代器序列中找出一子序列最后一次出现的位置
Search 在双迭代器序列中找出一个子序列第一次出现的位置
search_n 在单选代器序列中找出一个值连续 n次出现的位置
3.计数 count 在序列中统计某个值出现的次数
count_if 在序列中统计与某谓词(表达式)匹配的次数
4.比较 equal 两个序列中的对应元素都相同时为真
Mismatch 找出两个序列相异的第一个元豪
for_each():遍历容器元素,对每个元素执行相同的函数操作
Template
Fun For_each(InIt first, InIt last, Fun f);
InIt:可以是数组或输入迭代器 first:表示数组的起始元素的指针或输入迭代器的起始迭代指针 f:可以是全局函数或者是一元函数
该模板需数的含义是[first,last)之间的每个元案,作为函数f的参数传入并执行。
例:打印向量中每个整型元素的立方
使用 vector 容器存储一系列整数,并使用 for_each 算法对容器中的每个元素应用自定义的函数。在本例中,函数 PrintCube 计算每个元素的立方并将结果打印到控制台上
#include
#include
#include
using namespace std;
void PrintCube(int n)
{
cout << n * n * n << " ";
}
int main()
{
const int VECTOR_SIZE = 8;
typedef vector IntVector;
typedef IntVector::iterator IntVectorIt;
IntVector Numbers(VECTOR_SIZE);//创建容器并规定大小
IntVectorIt start, end, it;//定义了 IntVectorIt 类型的迭代器变量
for (int i = 0; i < VECTOR_SIZE; i++)//整数依次存储到 Numbers 容器中
Numbers[i] = i + 1;
start = Numbers.begin();//赋值
end = Numbers.end();
cout << "Numbers{";
for (it = start; it != end; it++)//for 循环打印出 Numbers 容器中的所有元素
cout << *it << " ";
cout << "}\n" << endl;
// for_each 算法,对 Numbers 容器中的每个元素应用 PrintCube 函数
for_each(start, end, PrintCube);
cout << "\n";
return 0;
}
(1)for_each 函数各参数的含义。start,end 表示向量的起始迭代指针、结束迭代指针,不是具体的值,比如for_each(start[0],end,PrintCube)是错误的,因为 start[0]表示的是向量中第一个元素的值 1。但 for_each(&start[0],end,PrintCube)是正确的,因为&start[0]表示的是第一个元素的地址。
(2) PrintCube函数必须有且只有一个参数,且参数类型与向量的模板类型一致。
例 求整数向量的和、最大值、最小值。
PrintInfo P = for_each(A, A + N, PrintInfo());
PS:使用 for_each 算法,对数组 A 中的每个元素应用 PrintInfo 类的对象。通过这个操作,我们将数组中的元素依次传递给 PrintInfo 类的函数调用运算符,并在其中进行总和、最大值和最小值的计算。将 for_each 的结果赋值给 PrintInfo 类的对象 P
(1)必须重载PrintInfo的operator()运算符,本例中即 void operator() (int x)在此函数内完成了求和、最大值、最小值的功能。
(2)主程序中 for_each(A,A+N,PrintInfo
使用 for_each 算法,对数组 A 中的每个元素应用 PrintInfo 类的对象。通过这个操作,我们将数组中的元素依次传递给 PrintInfo 类的函数调用运算符,并在其中进行总和、最大值和最小值的计算。将 for_each 的结果赋值给 PrintInfo 类的对象 P。
运行时,序先执行 PrintInfo
(3)对主程序中 PrintInfo template Fun for_each(InIt first, InIt last,Fun f); 返回值可以是函数对象,因此本例中等号左侧定义了 PrintInfo&P引用对象。当然只有当[first,last)中所有迭代值都执行了f 函数才最终返回函数对象。 例:下面采用模板传参技术,用STL提供的一元函数模板类,让上例只能求整型向量的和最大值最小值 查询操作是应用最广的操作,STL 主要提供了以下查询函数 find():在单迭代器序列中找出某个值第一次出现的位置。 find_if():在单迭代器序列中找出符合某谓词的第一个元素。 find_first_of():在双迭代器序列中找出一子序列中某元素第一次出现的位置 adjacent_find();在单迭代器序列中找出第一次相邻值相等元素的位置。 find_end():在双迭代器序列中找出一子序列最后一次出现的位置。 search():在双迭代器序列中找出一子序列第一次出现的位置。 search_n():在单选代器序列中找出一个值连续 n次出现的位置。 各个函数原型如下所示。 find: 原型: template InIt find(InIt first, InIt last, const T& val); 参数说明: InIt:输入选代器,first 表示起始元素的迭代器指针,last 表示结束元素的迭代器指针。 T:模板类型参数。 该函数是查询[first,last)间迭代器对应的元素值是否有等于 val的,若有则返回其迭代器指针;若无则返回 last。可知查询元素的个数范围是 N∈[0,last-first),由于要判定* (first+N)==val,因此板丁对应的类必须重运符“operator==”. find_if 原型: template 参数说明: InIt: 输人选代器,first 表示起始元的选代器指针,last 表示结束元的选代器指针。 Pred:普通全局函数或一元函数对象,返回值是 bool类型。该函数是查询[first,last)间迭代器对应的元素 *(first十i),若 pr( * (first+i))返回true,则返回此时的迭代器指针,表明满足条件的元素已找到;若没有找到则返回 last。 find_first_of 原型: template FwdItl find first of(FwdIt1 first1, FwdItl lastl,FwdIt2 first2, FwdIt2 last2); template FwdItl find first_of(FwdItl first1, FwdIt1 lastl,FwdIt2 first2, FwdIt2 last2,Pred pr); 参数说明: FwdIt1,FwdIt2;前向迭代器,first 表示起始元素的选代器指针,last 表示结束元素的迭代器指针。 Pred;二元全局函数或函数对象。 第一个原型含义是:若第一个前向迭代器[first1,last1)间第 N个元素与第二个前向代器[first2,last2)间某元素相等,且N最小,则返回 first1+N。表明第一个前向选代器wdIt1中有元素与第二个前向迭代器 FwdIt2 中的元素相等,否则返回 last1。 第二个原型与第一个类似,只不过要定义预判定函 pr( * (firstl+N),* (first2+M)) adjacent_find 原型: template FwdIt adjacent_find(FwdIt first,FwdIt last); template FwdIt adjacent_find(FwdIt first,FwdIt last, Pred pr); 参数说明: FwdIt:前向选代器,first 表示起始元的选代器指针,last 表示结束元素的选代器指针。 Pred:二元全局函数或函数对象。 第一个原型含义是,若前向代器 Fwdlt 中存在第N个元素,有*(first+N),且N最小,则表明有两个相邻元素是相等的,返回(first+N)否返回last。 第二个原型与第一个类似,只不过要定义预判定函数 pr( * (frst+N),*(first+N+1))。 find_end 原型: template FwdItI find_end(FwdItl first1, FwdItl lastl,Fwdit2 first2, Fwdit2 last2), template FwdIti find_end(Ewdit1 first1, EwdIt1 last1,wdit2 first2, Fwdit2 last2, Pred pe 参数说明: FwdIt1,FwdIt2:前向迭代器,first 表示起始元的迭代器指针,last 表示结束元的迭代器指针。 Pred:二元全局函数或函数对象。 第一个原型含义是:若前向迭代器 FwdItl 从第 N 个元开始:* (firstl+N)* (first2+0), * (firstl+N+1) = * (first2+ 1),..., * [firstl十 (last2- first2-1)]*[first2+(last2-first2-1)],且 N 最大,则返回(firstl+N),否则返回 last1。即返回FwdIt1 元素中最后一次完全与 FwdIt2 序列元素匹配的开始位置。 第二个原型与第一个类似,只不过要定义预判定函数 pr( * (first1+N+M),* (first2+N+M))。 search 原型: template FwdIt1 search(FwdIt1 first1, FwdIt1 last1,FwdIt2 first2,FwdIt2 last2); template FwdIt1 search(FwdIt1 first1, FwdIt1 last1,FwdIt2 first2, FwdIt2 last2,Pred pr); 参数说明: FwdIt1,FwdIt2:前向迭代器,first 表示起始元的迭代器指针,last 表示结束元素的迭代器指针。 Pred;二元全局函数或函数对象。 第一个原型含义是:若前向迭代器 FwdIt1从第 N个元素开始:* (first1十N)=* (first2+0), * (firstl+N+1)= * (first2+ 1),..., * [first] 十 (last2 - first2-1)]* [first2+(last2-first2-1)],且N最小,则返回(firstl十N),否则返回 last2。即返回在FwdIt1 元素中首次完全与 FwdIt2 序列元素匹配的开始位置。 第二个原型与第一个类似,只不过要定义预判定函数 pr( * (first1+N+M),* (irst2+M)) Search_n template FwdIt search_n(Fwdit first, Fwdit last,Dist n, const T& val); template spwdrt seareh n(FwdIt firat, fwdit last,Dist n, const Ts val, Pred pr); 参数说明:。FwdIt:前向选代器,first 表示起始元素的选代器指针,last 表示结束元素的迭代器指针。count:要搜索的连续出现次数,value:要搜索的特定值。n: 整型变量,表示大小。 val:待比较的值。 Pred:二元全局函数或函数对象。 第一个原型含义是:在前向迭代器 FwdIt 中,从第 N 个元开始连续的n个元素满足;* (first+N)=val,* (first+1)= val,...,* (first+N+n)-val,且 N最小,则返回*(first+N),否则返回 last。 第二个原型与第一个类似,只不过要定义预判定函数 pr( * (first1+N+M),val)。 例: 7个查询函数的简单应用。 find_if 和 find 是C++ STL算法库中的两个函数,用于在容器或者数组中查找元素。它们的区别如下: 1.功能不同: find 函数用于在范围内查找第一个与指定值相等的元素,并返回指向该元素的迭代器(或指针)。 find_if 函数用于在范围内查找第一个满足指定条件(通过谓词函数)的元素,并返回指向该元素的迭代器(或指针)。 2.查找条件不同: find 函数通过比较相等运算符(==)来确定元素是否与指定值相等。 find_if 函数通过调用用户自定义的谓词函数(predicate function)来判断元素是否满足特定条件。 3.使用方式不同: find 函数的调用形式为 find(first, last, value),其中 first 和 last 是表示范围的迭代器(或指针),value 是要查找的特定值。 find_if 函数的调用形式为 find_if(first, last, predicate),其中 first 和 last 是表示范围的迭代(或指针),predicate 是一个谓词函数,用于判断元素是否满足条件。 例 :根据学号询学生信息,且已知学号是关键字 理解 Student类必须重载运算符“==”。当执行 find(begin,end,nFindNO)语句时,[begin,end)间的每一个迭代指针表示的 Student 对象都要与 nFindNO 比较,判断是否相等,因此必须重载 Student类中的“==”运算符。由于 nFindNO 是整型,因此重载的“=="运算符参数必须是整型数。 1. 下面哪个algorithm定义的函数支持对数据传入自定义的处理算法( ) A. for B. find_if C. count D. swap 2. 下面哪个不属于algorithm算法定义的函数(D) A. for_each B. find_if C. count D. less<>//属于函数对象functional 3.下面哪个函数实现遍历容器元素,对每个元素执行相同的函数操作() A. for B. for_each C. count D. swap#include
8.2 查询
8.2.1主要函数
8.2.2示例分析
#include
#include
8.3 习题