Algorithm
中文意思是算法,是一个计算的具体步骤,常用于数据处理、计算以及自动推理。它作为 C++
标准模版库 STL
中最重要的头文件之一,其提供了大量非成员模版函数,例如排序操作、二分查找操作、集合操作以及堆操作等。同时可以通过迭代器或指针访问任何对象序列,例如 STL
容器数组或实例。更多的了解请参考官方文档 。
本实训主要设置了四个关卡:第一关和第二关介绍了 Algorithm
中的二分搜索操作 binary_search
及其相关搜索操作;第三关是修改序列操作 Modifying sequence operations
;第四关讲的是非修改序列操作 Non-modifying sequence operations
。最后在每个关卡都设置了实例,考察学员对所讲内容的理解和在线编程能力。
第1关:二分查找:在N个无序整数里面查找M个指定整数
任务描述
本关任务:给定包含 N 个整数的无序序列 S(a1,a2,..,aN),以及 M 次查询序列 Q(b1,b2,..,bM),判定 bj 是否在序列 S 中。
相关知识
为了完成本关任务,你需要掌握:1.解题思路,2.快速排序算法,3.二分查找算法。
解题思路
本关卡问题清晰,解法简单:对于每次查询bj,在序列S中遍历ai是否等于bj。虽然该解法实现简单,但是执行效率低,运算复杂度高O(N×M)。
高效解法:首先运用快速排序算法,将无序序列变为有序(升序),然后对每次查找操作,使用二分查找算法判断元素是否存在。该解法实现稍微有点复杂,但是执行效率高,运算复杂度低O(N×logN+M×logN)。
快速排序算法
快速排序算法的背景和原理前面已有很多实训介绍过了,为了方便实现,一般使用 algorithm
中模板函数 sort
,请认真参考实训《算法与竞赛(第2章) - C++与Algorithm基础一》 的第三个关卡,之后的实训将不再对sort
进行讲解。
二分查找算法
二分查找算法也称折半查找算法 Binary Search Algorithm
,它是一种效率较高的查找方法,复杂度为O(logN)。二分查找算法要求线性表(序列)必须采用顺序存储结构,而且表中元素按关键字有序排列。
核心思想:将表中间位置记录的关键字与待查找的关键字进行比较,如果两者相等,则查找成功;否则利用中间位置记录将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表。重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功。
幸运的是,C++
在 Algorithm
算法模板中集成了二分查找算法,这样仅仅调用一个模板函数 binary_search
就可以实现指定元素(关键字)的查找了。其函数原型及其应用实例如下:
1 \\ binary_search函数原型 2 default (1): 3 template <class ForwardIterator, class T> 4 bool binary_search (ForwardIterator first, ForwardIterator last, const T& val); 5 custom (2): 6 template <class ForwardIterator, class T, class Compare> 7 bool binary_search (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 8 \\ binary_search应用实例 9 int arr[4] = {1,2,3,4}; // 升序数组 10 bool judge1 = binary_search(arr, arr+4, 1); // judge1结果为true 11 bool judge2 = binary_search(arr, arr+4, 5); // judge2结果为false
本关卡使用的是整型数据,使用默认的模板函数即可。若有兴趣学习自定义数据类型下的二分查找,请参考实训《算法与竞赛(第2章) - C++与Algorithm基础一》第三个关卡对自定义数据类型的相关操作。
编程要求
本关的编程任务是补全右侧代码片段 main
中 Begin
至 End
中间的代码,具体要求如下:
在 main
中,读取N
个无序序列,并存储在数组中,然后对无序数组进行排序,最后调用二分查找算法完成 M
次指定元素的查找任务,并输出查找结果。若在序列中,输出 bj in array
,否则输出 bj not in array
。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:
7
2 5 9 5 5 3 1
3
4 7 5
预期输出:
4 not in array
7 not in array
5 in array
输入格式:
第一行:序列元素个数N
第二行:N个无序序列元素
第三行:查询次数M
第四行:M个待查询元素
输出格式:
输出M行,每行对应查询结果,每行末尾换行!!!
开始你的任务吧,祝你成功!

1 // 2 // main.cpp 3 // step1 4 // 5 // Created by ljpc on 2018/7/8. 6 // Copyright ? 2018年 ljpc. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <algorithm> 11 #include <cstdio> 12 13 using namespace std; 14 15 int main(int argc, const char * argv[]) 16 { 17 18 // 请在这里补充代码,完成本关任务 19 /********** Begin *********/ 20 int n,m; 21 cin>>n; 22 int a[n+10];//需要注意的是,有的编译器支持这种定义方法,有的不支持 23 //可以考虑直接定义一个很大的数组 24 //如果这样定义的话,顺序不能颠倒,只有有了n之后才可以定义这个数组 25 26 for(int i=1;i<=n;i++) cin>>a[i];//依次输入这n个无序序列并储存在数组中 27 28 sort(a,a+n+1);//利用sort函数对无序数组进行排序,sort默认使用 < 号 29 30 cin>>m; 31 int b[m+10]; 32 for(int i=1;i<=m;i++) 33 cin>>b[i]; 34 35 for(int i=1;i<=m;i++){//利用for循环依次对数组中存储的每一个数在有序数组a中进行查找 36 if(binary_search(a,a+n,b[i])) //binary_search函数题目中有写到,是对有序数组进行查找的 37 cout<<b[i]<<" in array"<<endl; 38 else cout<<b[i]<<" not in array"<<endl; 39 } 40 /********** End **********/ 41 42 return 0; 43 }
第2关二分查找:在N个有序整数里面查找M个指定整数的闭区间位置
任务描述
本关任务:给定包含N个整数的升序序列S(a1,a2,..,aN),以及M次查询序列Q(b1,b2,..,bM),求bj在序列S中的闭区间位置(测试数据保证bj存在序列S中),例如2
在升序序列 1,2,2,3
中的闭区间位置为 [1,2]
。
相关知识
为了完成本关任务,你需要掌握:1.模板函数 lower_bound
,2.模板函数 upper_bound
,3.模板函数 equal_range
。
模板函数 lower_bound
上个关卡介绍了 binary_search
的模板函数,实际上它的内部实现是基于 lower_bound
函数实现的,通过 lower_bound
在有序序列里查找不小于关键字的元素,并返回元素索引位置最低的地址,最后根据地址来判断是否查找成功,代码如下:
1 template <class ForwardIterator, class T> 2 bool binary_search (ForwardIterator first, ForwardIterator last, const T& val){ 3 first = std::lower_bound(first,last,val); 4 return (first!=last && !(val<*first)); 5 //first!=last为true:说明找到一个不小于关键字的元素 6 //!(val<*first) 为true:说明该元素与待查找关键字相等 7 }
模板函数 lower_bound
的基本用途是查找有序区间中第一个 大于或等于
某给定值的元素的位置,由此本关卡的任务可以利用 lower_bound
获取序列中等于待查找关键字的元素的位置。其函数原型及其应用实例如下:
1 \\ 函数原型 2 default (1): 3 template <class ForwardIterator, class T> 4 ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last, const T& val); 5 custom (2): 6 template <class ForwardIterator, class T, class Compare> 7 ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,const T& val, Compare comp); 8 \\ 应用实例 9 int arr[5] = {1,2,2,4,5}; 10 int a = lower_bound(arr, arr+5, 2) - arr; // a结果为1
模板函数 upper_bound
模板函数 upper_bound
的基本用途与 lower_bound
相对,是查找有序区间中第一个 大于
某给定值的元素的位置,由此本关卡的任务可以利用 upper_bound
获取序列中第一个 大于
待查找关键字的元素的位置,往前移一位就是最后一个等于待查找关键字的元素的位置。其函数原型及其应用实例如下:
1 \\ 函数原型 2 default (1): 3 template <class ForwardIterator, class T> 4 ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val); 5 custom (2): 6 template <class ForwardIterator, class T, class Compare> 7 ForwardIterator upper_bound (ForwardIterator first, ForwardIterator last, const T& val, Compare comp); 8 \\ 应用实例 9 int arr[5] = {1,2,2,4,5}; 10 int b = upper_bound(arr, arr+5, 2) - arr; // b结果为3
模板函数 equal_range
模板函数 equal_range
综合了 lower_bound
和 upper_bound
的功能,通过内部调用这两个上下界查找函数,返回两个地址并组成 pair
:第一个地址是序列中第一个大于等于待查找关键字的元素位置,而第二个地址是第一个大于待查找关键字的元素位置。因为本关卡的数据保证在序列中存在待查找关键字,所以 equal_range
返回的是一个左闭右开的区间位置。其函数原型及其应用实例如下:
1 default (1): 2 template <class ForwardIterator, class T> 3 pair<ForwardIterator,ForwardIterator> 4 equal_range (ForwardIterator first, ForwardIterator last, const T& val); 5 custom (2): 6 template <class ForwardIterator, class T, class Compare> 7 pair<ForwardIterator,ForwardIterator> 8 equal_range (ForwardIterator first, ForwardIterator last, const T& val, Compare comp);
模板函数 equal_range
基于 lower_bound
和 upper_bound
的函数内部实现如下:
1 \\ 函数原型 2 template <class ForwardIterator, class T> 3 pair<ForwardIterator,ForwardIterator> 4 equal_range (ForwardIterator first, ForwardIterator last, const T& val){ 5 ForwardIterator it = std::lower_bound (first,last,val); 6 return std::make_pair ( it, std::upper_bound(it,last,val) ); 7 } 8 \\ 应用实例 9 int arr[5] = {1,2,2,4,5}; 10 auto bounds = equal_range(arr, arr+5, 2); 11 int a = bounds.first-arr; // a结果为1 12 int b = bounds.second-arr; // b结果为3
编程要求
本关的编程任务是补全右侧代码片段 main
中 Begin
至 End
中间的代码,具体要求如下:
在 main
中,读取 N
个升序序列,并存储在数组中,基于 lower_bound
和 upper_bound
算法(或 equal_range
)完成M
次指定元素的查找任务,并输出查找闭区间结果(输出格式严格遵循样例)。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入:
7
1 1 2 3 5 5 6
2
5 6
预期输出:
5 at order array position [4,5]
6 at order array position [6,6]
输入格式:
第一行:序列元素个数N
第二行:N个升序序列元素
第三行:查询次数M
第四行:M个待查询元素
输出格式:
输出M行,每行对应查询结果,每行末尾换行!!!
开始你的任务吧,祝你成功!

1 // 2 // main.cpp 3 // step2 4 // 5 // Created by ljpc on 2018/7/8. 6 // Copyright ? 2018年 ljpc. All rights reserved. 7 // 8 9 #include <iostream> 10 #include <algorithm> 11 #include <cstdio> 12 using namespace std; 13 14 int main(int argc, const char * argv[]) 15 { 16 17 // 请在这里补充代码,完成本关任务 18 /********** Begin *********/ 19 int n; 20 cin>>n;//获取有序序列的元素个数,便于利用循环输入序列 21 int a[n+10];//定义一个数组用于存储序列 22 for(int i=0;i<=n-1;i++){//利用for循环不断输入序列 23 //要注意一下这里,需要从数组的第一个位置开始记录 24 cin>>a[i]; 25 } 26 27 int m; 28 cin>>m;//获取要在有序序列中的查询次数 29 int b[m+10];//定义数组b用于存储待查找元素 30 for(int i=0;i<=m-1;i++){ 31 //要注意一下这里,需要从数组的第一个位置开始记录 32 cin>>b[i]; 33 34 } 35 for(int i=0;i<=m-1;i++){ 36 auto bounds = equal_range(a,a+n,b[i]); 37 //利用函数equal_range查询 38 int j=bounds.first-a;//序列中第一个【大于等于】待查找关键字的元素位置 39 int p=bounds.second-a;//序列中第一个【大于】待查找关键字的元素位置 40 cout<<b[i]<<" at order array position ["<<j<<","<<p-1<<"]"<<endl; 41 //因为p是大于的位置,而我们要求的是闭区间,所以应该减去 1 42 }
如果因为个人习惯问题,喜欢将for循环中的i从1开始记录的话,代码应该这么写:

1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 using namespace std; 5 6 int main(int argc, const char * argv[]) 7 { 8 9 // 请在这里补充代码,完成本关任务 10 /********** Begin *********/ 11 int n; 12 cin>>n;//获取有序序列的元素个数,便于利用循环输入序列 13 int a[n+10];//定义一个数组用于存储序列 14 for(int i=1;i<=n;i++){//利用for循环不断输入序列 15 cin>>a[i]; 16 } 17 18 int m; 19 cin>>m;//获取要在有序序列中的查询次数 20 int b[m+10];//定义数组b用于存储待查找元素 21 for(int i=1;i<=m;i++){ 22 //要注意一下这里,需要从数组的第一个位置开始记录 23 cin>>b[i]; 24 25 } 26 for(int i=1;i<=m1;i++){ 27 auto bounds = equal_range(a+1,a+n+1,b[i]); 28 //利用函数equal_range查询 29 int j=bounds.first-a;//序列中第一个【大于等于】待查找关键字的元素位置 30 int p=bounds.second-a;//序列中第一个【大于】待查找关键字的元素位置 31 cout<<b[i]<<" at order array position ["<<j<<","<<p-1<<"]"<<endl; 32 //此时,j和 p所代表的地址实际上比要查找的关键字的地址还要大于 1,所以应该都减 1 33 //又因为p是大于的位置,而我们要求的是闭区间,所以应该减去 2 34 } 35 36 37 /********** End **********/ 38 39 return 0; 40 }
第3关修改序列(数组)操作的应用
任务描述
本关任务:编写一个程序,实现复制Copy_N
,交换Swap
,取代Replace
,填充Fill
,倒置Reverse
,滚动Rotate
等修改序列操作。
相关知识
为了完成本关任务,你需要掌握:1.复制Copy_N
,2.交换Swap
,3.取代Replace
,4.填充Fill
,5.倒置Reverse
,6.滚动Rotate
。
复制Copy_N
Algorithm
中有两个常用的复制函数:copy
和copy_n
,其中copy
复制整个数组到新的数组中,而copy_n
则是可选择的复制前n
个元素到新的数组。 copy
函数原型及其应用实例如下,参数first
为数组首地址,参数last
为数组尾地址,参数result
为新数组首地址:
1 \\ 函数原型 2 template <class InputIterator, class OutputIterator> 3 OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result); 4 \\ 应用实例 5 int arr1[4] = {1,3,2,4}; 6 int arr2[4]; 7 copy(arr1, arr1+4, arr2); 8 \\或者 arr2 = copy(arr1, arr1+4, arr2);
copy_n
函数原型及其应用实例如下,参数first
为数组首地址,参数n
为要复制的数组元素个数,参数result
为新数组首地址:
1 \\ 函数原型 2 template <class InputIterator, class Size, class OutputIterator> 3 OutputIterator copy_n (InputIterator first, Size n, OutputIterator result); 4 \\ 应用实例 5 int arr1[4] = {1,3,2,4}; 6 int arr2[4]; 7 copy_n(arr1, 4, arr2);
交换Swap
Algorithm
中交换模板函数为swap
,传入两个参数地址引用,功能是交换这两个参数的数值,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class T> void swap (T& a, T& b) 3 \\ 应用实例 4 int a=1, b=2; 5 swap(a, b); 6 \\ a结果为2,b结果为1
取代Replace
Algorithm
中取代模板函数为replace
,传入参数first
为数组首地址,参数last
为数组尾地址,要被替换的旧元素为参数old_value
,替换的新的元素为参数new_value
,函数功能是将数组中所有的old_value
替换为new_value
,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class ForwardIterator, class T> 3 void replace (ForwardIterator first, ForwardIterator last, const T& old_value, const T& new_value); 4 \\ 应用实例 5 int arr[4] = {1,2,2,3}; 6 replace(arr, arr+4, 2, 0); 7 \\ arr结果为{1,0,0,3}
填充Fill
Algorithm
中填充模板函数为fill
,传入参数first
为数组首地址,参数last
为数组尾地址,填充值为参数val
,函数功能是将数组中的所有元素都重新赋值为val
,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class ForwardIterator, class T> 3 void fill (ForwardIterator first, ForwardIterator last, const T& val); 4 \\ 应用实例 5 int arr[4] = {1,2,2,3}; 6 fill(arr, arr+4, 5); 7 \\ arr结果为{5,5,5,5}
特别的,类似的填充函数还有memset
,在头文件string.h
中,但是赋值有限,一般仅限于-1
,0
,若设置为其他数值,则实际结果有误。
倒置Reverse
Algorithm
中倒置模板函数为reverse
,传入参数first
为数组首地址,参数last
为数组尾地址,函数功能是将数组中的所有元素对称交换,例如比如1 2 3
,变为3 2 1
,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class BidirectionalIterator> 3 void reverse (BidirectionalIterator first, BidirectionalIterator last); 4 \\ 应用实例 5 int arr[4] = {1,2,3,4}; 6 reverse(arr, arr+4); 7 \\ arr结果为{4,3,2,1}
滚动Rotate
Algorithm
中滚动模板函数为rotate
,传入参数first
为数组首地址,参数last
为数组尾地址,而参数middle
则是数组中要滚动的最后一个元素的后一个地址,滚动完成后该地址将成为首地址,比如数组arr=[0,1,2,3,4]
,相应的参数为first=arr
,last=arr+5
,middle=arr+3
,则滚动后的结果为3 4 0 1 2
,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class ForwardIterator> 3 ForwardIterator rotate (ForwardIterator first, ForwardIterator middle, ForwardIterator last); 4 \\ 应用实例 5 int arr[5] = {0,1,2,3,4}; 6 rotate(arr, arr+3, arr+5); 7 \\ arr结果为{3,4,0,1,2}
编程要求
本关的编程任务是补全右侧代码片段Copy_N
,Swap
,Reverse
,Replace
,Fill
,和Rotate
中Begin
至End
中间的代码,具体要求如下:
- 在
Copy_N
中,复制数组arr
中前n
个元素到一个新的数组,并将新数组作为函数返回值。 - 在
Swap
中,实现整数x
和整数y
数值交换,因为传入的参数为地址引用,所以对x
和y
的修改都是真实有效的修改,也就是说会改变原来的值。 - 在
Reverse
中,实现数组arr
所有元素首尾倒置,即交换arr[0]
与arr[n-1]
,arr[1]
与arr[n-2]
,以此类推。 - 在
Replace
中,将数组arr
中所有的元素x
都替换为新的元素y
。 - 在
Fill
中,实现数组arr
的填充,将所有的元素赋值为元素z
。 - 在
Rotate
中,实现m
次数组arr
左向滚动,即每次数组滚动将arr[0]
移动到数组末尾,然后元素依次往前移动一位。
以上所有功能学员可以基于Algorithm
模板库调用相应的模板函数来实现,也可以自己编写具体代码来实现,进一步理解其原理和作用。
测试说明
平台将自动编译补全后的代码,并随机生成若干组测试数据,接着根据程序的输出判断程序是否正确(学员不需要关注测试用例,只需实现上述的编程要求即可)。
开始你的任务吧,祝你成功!

1 // 2 // code.cpp 3 // step3 4 // 5 // Created by ljpc on 2018/7/12. 6 // Copyright ? 2018年 ljpc. All rights reserved. 7 // 8 9 #include "code.h" 10 11 int* Copy_N(int *arr, int n) 12 // 函数功能:复制数组arr中前n个元素并作为函数返回值 13 { 14 // 请在这里补充代码,完成本关任务 15 /********** Begin *********/ 16 int *arr2 = new int[n]; 17 for(int i=0;i<n;i++){ 18 arr2[i]=arr[i]; 19 } 20 return arr2; 21 /********** End **********/ 22 } 23 24 void Swap(int &a, int &b) 25 // 函数功能:交换参数x和参数y 26 { 27 // 请在这里补充代码,完成本关任务 28 /********** Begin *********/ 29 swap(a,b); 30 31 /********** End **********/ 32 } 33 34 void Replace(int *arr, int n, int x, int y) 35 // 函数功能:在数组arr中将元素x替换为y,其中n为数组个数 36 { 37 // 请在这里补充代码,完成本关任务 38 /********** Begin *********/ 39 replace(arr,arr+n,x,y); 40 41 /********** End **********/ 42 } 43 44 void Fill(int *arr, int n, int z) 45 // 函数功能:将大小为n的数组的所有元素填充为元素z 46 { 47 // 请在这里补充代码,完成本关任务 48 /********** Begin *********/ 49 fill(arr,arr+n,z); 50 51 /********** End **********/ 52 } 53 54 void Reverse(int *arr, int n) 55 // 函数功能:倒置数组arr的元素,比如1 2 3,变为3 2 1,其中n为数组个数 56 { 57 // 请在这里补充代码,完成本关任务 58 /********** Begin *********/ 59 reverse(arr,arr+n); 60 61 /********** End **********/ 62 } 63 64 void Rotate(int *arr, int n, int m) 65 // 函数功能:向左边滚动m个元素,并补到数组右边,比如 1 2 3 4,滚动m=2个元素,结果为3 4 1 2,其中n=4是数组个数 66 { 67 // 请在这里补充代码,完成本关任务 68 /********** Begin *********/ 69 rotate(arr,arr+m,arr+n); 70 71 /********** End **********/ 72 }
第4关:非修改序列(数组)操作的应用
任务描述
本关任务:编写一个程序,实现无序数组查找指定元素Find
,无序数组查找指定数组子序列Find_End
,指定元素个数统计Count
,两个数组相等比较Equal
等非修改序列操作。
相关知识
为了完成本关任务,你需要掌握:1.无序数组查找指定元素Find
,2.无序数组查找指定数组子序列Find_End
,3.指定元素个数统计Count
,4.两个数组相等比较Equal
。
无序数组查找指定元素Find
与上个实训介绍的二分查找binary_search
不一样,Algorithm
中的模板函数find
可以在无序数组中的查找指定元素x
,若存在则返回第一个x
所在的地址,否则返回数组尾地址,其函数原型及其应用实例如下,其中传入参数first
为数组首地址,参数last
为数组尾地址,待查找指定元素为参数val
:
1 \\ 函数原型 2 template <class InputIterator, class T> 3 InputIterator find (InputIterator first, InputIterator last, const T& val); 4 \\ 应用实例 5 int arr[4] = {1,3,2,3}; 6 int *p = find(arr, arr+4, 3); // p结果为地址arr+1 7 int *q = find(arr, arr+4, 0); // q结果为地址arr+4
无序数组查找指定数组子序列Find_End
Algorithm
中的模板函数find_end
可以在无序数组arr1
中的查找指定子数组arr2
是否存在,若存在则返回待查子数组arr2
最后出现在原数组arr1
的地址,否则返回原数组的尾地址,例如arr1=[0,3,4,3,4]
,arr2=[3,4]
,返回结果为arr1+3
,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class ForwardIterator1, class ForwardIterator2> 3 ForwardIterator1 find_end (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2); 4 \\ 应用实例 5 int arr[5] = {0,3,4,3,4}; 6 int arr1[2] = {3,4}; 7 int arr2[2] = {3,5}; 8 int *p = find_end(arr, arr+5, arr1, arr1+2); // p结果为地址arr+3 9 int *q = find_end(arr, arr+5, arr2, arr2+2); // q结果为地址arr+5
特别的,如想要第一次出现的地址,模板函数search
可以实现这一功能,使用方式同上,其函数原型如下:
1 template <class ForwardIterator1, class ForwardIterator2> 2 ForwardIterator1 search (ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2);
指定元素个数统计Count
Algorithm
中的模板函数count
可以在数组中统计指定元素x
出现的次数,传入参数first
为数组首地址,参数last
为数组尾地址,参数x
为待统计的指定元素,其函数原型及其应用实例如下:
1 \\ 函数原型 2 template <class InputIterator, class T> 3 typename iterator_traits<InputIterator>::difference_type count (InputIterator first, InputIterator last, const T& val); 4 \\ 应用实例 5 int arr[5] = {0,3,4,3,4}; 6 int cnt = count(arr, arr+5,3); // cnt结果为2
两个数组相等比较Equal
两个数组相等意思是数组个数相同,对应位置上的元素值也相同,Algorithm
中的模板函数equal
就可以比较两个数组是否相等,返回比较真值,其函数原型及其应用实例如下,其中参数first1
是第一个数组的首地址,参数last1
是第一个数组的尾地址,参数first2
是第二个参数的首地址,默认两个数组元素个数是相同的,否则没有比较意义:
1 \\ 函数原型 2 template <class InputIterator1, class InputIterator2> 3 bool equal (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2); 4 \\ 应用实例 5 int arr1[2] = {3,4}; 6 int arr2[2] = {3,4}; 7 int arr3[2] = {3,5}; 8 bool judge1 = equal(arr1, arr1+2, arr2); // judge1结果为地址true 9 bool judge2 = equal(arr1, arr1+2, arr3); // judge2结果为地址false
编程要求
本关的编程任务是补全右侧代码片段Find
,Find_End
,Count
和Equal
中Begin
至End
中间的代码,具体要求如下:
- 在
Find
中,对于给定的数组首地址和尾地址,查找元素x
是否在数组中,若在则返回第一个x
所在的地址,否则返回数组尾地址。 - 在
Find_End
中,对于给定数组arr1
及其个数n1
,数组arr2
及其个数n2
,查找数组arr2
是否在arr1
中,若数组arr2
在数组arr1
中出现,则返回数组arr2[0]
在arr1
中最后一次出现的地址,否则,返回数组arr1
尾地址,即arr1+n1
。 - 在
Count
中,统计指定元素x
在数组中出现的次数。 - 在
Equal
中,对于给定数组arr1
及其个数n1
,数组arr2
,比较两个数组是否相等,若相等则返回true
,否则返回false
。
以上所有功能学员可以基于Algorithm
模板库调用相应的模板函数来实现,也可以自己编写具体代码来实现,进一步理解其原理和作用。
测试说明
平台将自动编译补全后的代码,并随机生成若干组测试数据,接着根据程序的输出判断程序是否正确(学员不需要关注测试用例,只需实现上述的编程要求即可)。
开始你的任务吧,祝你成功!

1 // 2 // code.cpp 3 // step4 4 // 5 // Created by ljpc on 2018/7/14. 6 // Copyright © 2018年 ljpc. All rights reserved. 7 // 8 9 #include "code.h" 10 11 int* Find(int *first, int *last, int x) 12 // 函数功能:给定数组首地址和尾地址,若x在数组中,返回第一个x所在的地址,否则返回尾地址 13 { 14 // 请在这里补充代码,完成本关任务 15 /********** Begin *********/ 16 //int static *q = find(*first,*last,x); 17 return find(first,last,x); 18 /********** End **********/ 19 } 20 21 int* Find_End(int *arr1, int n1, int *arr2, int n2) 22 // 函数功能:给定数组arr1,个数n1,数组arr2,个数n2, 23 // 若数组arr2在数组arr1中出现(连续),则返回数组arr2[0]在arr1中最后一次出现的地址 24 // 否则,返回数组arr1尾地址,即arr1+n1 25 { 26 // 请在这里补充代码,完成本关任务 27 /********** Begin *********/ 28 int *q=find_end(arr1,arr1+n1,arr2,arr2+n2); 29 return q; 30 /********** End **********/ 31 } 32 33 int Count(int *first, int *last, int x) 34 // 函数功能:给定数组首地址和尾地址,统计数组中元素x的个数,并返回 35 { 36 // 请在这里补充代码,完成本关任务 37 /********** Begin *********/ 38 return count(first,last,x); 39 /********** End **********/ 40 } 41 42 bool Equal(int *arr1, int n1, int *arr2) 43 // 函数功能:给定数组arr1,个数n1,数组arr2,(两个数组个数相同),判断两个数组是否相等 44 { 45 // 请在这里补充代码,完成本关任务 46 /********** Begin *********/ 47 bool a; 48 for(int i=0;i<n1;i++){ 49 if(arr1[i]==arr2[i])a=true; 50 else { 51 a=false; 52 break; 53 } 54 } 55 return a; 56 /********** End **********/ 57 }