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 }