首先解釋下標題的含義:
在網上看了一位大牛寫的基礎算法相關的博文,感覺自己不是天賦異稟,所以決定自己實現一遍當作交作業。當然歡迎大家審查,提出優化意見。
開篇:
今天這篇博文是關於數組查找的,很簡單。
算法是計算機的生命。沒有算法,就沒有軟件,計算機也就成了一個冰冷的機器,沒有什麼實用價值。很多人認爲,算法是數學的內容,學起來特別麻煩。我們不能認爲這種觀點是錯誤的。但是我們也知道,軟件是一種複合的技術,如果一個人只知道算法,但是不能用編程語言很好地實現,那麼再優秀的算法也不能發揮作用。一個人只有有了很好的計算機知識和數學知識,才能在算法的學習上不斷進步。不管算法都麼簡單,都要自己親手實踐,只有不斷認識錯誤、不斷髮現錯誤,才能不斷提高自己的編程能力,不斷提高自己的業務水平。
這裏取名一步一步寫算法的目的主要有兩個:第一,保證我們的算法都是大家可以學得會,看的懂的;第二,保證我們的算法是健壯的、可以測試的。所以在編寫的過程中,我們的算法開發過程是伴隨着測試用例增加的,沒有測試用例保證的代碼只是一段無序的字符而已,沒有什麼價值。
其實任何算法都有自己的應用環境和應用場景,沒有算法可以適用於所有的場景。這一點希望大家明白。同時,我們也要清楚複雜的算法都是由普通的算法構成的,沒有普通的算法就沒有複雜的算法可言,所以複雜變簡單,由大化小,這就是算法分治遞歸的基本思想。
上面的內容我感覺寫的比較好,所以搬運了。下面正式實現自己的版本。
1.數組查找函數1.0版本:
int Find_Array(int arr[], unsigned length, const int& value){
int index = 0;
return index;
}
測試:
#include <iostream>
#include <assert.h>
//存在返回下標,否則返回-1表示查找失敗。
int Find_Array(int arr[], unsigned length, const int& value){
int index = 0;
return index;
}
static void test1(){
int arr[10] = { 0 };
assert(Find_Array(nullptr, 10, 1)==-1);
assert(Find_Array(arr, 0, 1) == -1);
}
int main(){
test1();
}
通過測試可以看出程序的不健壯,需要對入口進行修改。
2.0版本:
int Find_Array(int arr[], unsigned length, const int& value){
if (arr == nullptr || length == 0)
return -1;
int index = 0;
return index;
}
//可以看到我們對入口限制。
3.0版本:
int Find_Array(int arr[], std::size_t length, const int& value){
if (arr == nullptr || length == 0)
return -1;
for (std::size_t index = 0; index < length; ++index){
if (arr[index] == value)
return index;
continue;
}
return -1;
}
static void test1(){
int arr[10] = { 1,2};
assert(Find_Array(nullptr, 10, 1)==-1);
assert(Find_Array(arr, 10, 1) == 0);
}
4.0優化版本:
1)用指針進行優化:
int Find_Array(int arr[], std::size_t length, const int& value){
if (arr == nullptr || length == 0)
return -1;
for (std::size_t index = 0; index < length; ++index){
if (*(arr+index)== value)
return index;
continue;
}
return -1;
}
2)對形參進行優化:
using array = int(&)[10];//數組類型的引用。
int Find_Array(array arr, const int& value){
if (arr == nullptr)
return -1;
for (std::size_t index = 0; index < 10; ++index){
if (arr[index] == value)
return index;
continue;
}
----------
C++ 11:
using array = int(&)[10];//數組類型的引用。
int Find_Array(array arr, const int& value){
int index = 0;
for (const auto& x : arr){
if (x == value)
return index;
++index;
continue;
}
return -1;
}
void test(){
int arr[10] = { 1, 2 };
assert(Find_Array(arr, 10) == -1);
assert(Find_Array(arr, 2) == 1);
}
//我們省略了數組大小的參數,不過上面的寫法存在一定的侷限性。
----------
3)模版函數版本:
template<class T>
int Find_Array(const T* const &arr, const std::size_t length, const T& value){
if (arr == nullptr || length == 0)
return -1;
auto beg = arr, end = beg + length;
while (beg != end)
if (*beg++ == value)
return beg - arr-1;
return -1;
}
void test(){
int arr[10] = { 1, 2 };
assert(Find_Array(arr, 10,1) ==0);
assert(Find_Array(arr, 10,3) == -1);
}
相關說明:
1.爲什麼用size_t?避免數組長度小於0.
2.參數的優化:儘量用const引用進行優化,錙銖必較。
3.測試平臺:VS 2013+Win 7.
二次優化版本:
最近學了點標準庫的內容,所以用向量和標準版定義的array 類型實現下。
#include <iostream>
#include <assert.h>
#include <vector>
#include <array>
//存在返回下標,否則返回-1表示查找失敗。
//vector 版本。
int Find_Array(const std::vector<int>& ivec, const int& value){
//不使用下標版本,直接使用迭代器。
auto beg = ivec.begin(), end = ivec.end();
if (beg == end)
return -1;
int index = 0;
while (beg != end)
if (*beg++==value)
return beg - ivec.begin() - 1;
return -1;
}
void test1(){
std::vector<int> ivec = { 1, 2, 3 };
assert(Find_Array(ivec,2)== 1);
assert(Find_Array(ivec, 10) == -1);
assert(Find_Array(std::vector<int>(), 10) == -1);
}
//標準庫的數組版本。
int Find_Array(const std::array<int,10>& arr, const int& value){
if (arr.empty())
return -1;
int index = 0;
for (const auto& x : arr){
if (x == value)
return index;
++index;
continue;
}
return -1;
}
void test2(){
std::array < int, 10 > arr= {1, 2, 3};
assert(Find_Array(arr, 2) == 1);
assert(Find_Array(arr, 10) == -1);
assert(Find_Array(std::array<int,10>(), 10) == -1);
}
int main(){
test1();
test2();
system("pause");
return 0;
}
----------
//來個可變參數列表試試。
int Find_Array(const std::initializer_list<int>& i1, const int& value){
auto beg = i1.begin(), end = i1.end();
if (beg == end)
return -1;
int index = 0;
while (beg != end)
if (*beg++ == value)
return beg - i1.begin() - 1;
return -1;
}
void test3(){
assert(Find_Array(std::initializer_list<int>{1, 2, 3}, 1) == 0);
assert(Find_Array(std::initializer_list<int>(), 10) == -1);
}
Summary:
1.算法的思路非常簡單,我只不過閒的無聊重寫了一遍。查找涉及到基本操作應該是遍歷,計數等操作。
2.學會一步步優化算法。
3.拓寬算法的可用性。
4.保證健壯性。
5.博文參考:原文地址,戳我進去