算法交作業之開篇(一)

首先解釋下標題的含義:
在網上看了一位大牛寫的基礎算法相關的博文,感覺自己不是天賦異稟,所以決定自己實現一遍當作交作業。當然歡迎大家審查,提出優化意見。

開篇:

今天這篇博文是關於數組查找的,很簡單。
算法是計算機的生命。沒有算法,就沒有軟件,計算機也就成了一個冰冷的機器,沒有什麼實用價值。很多人認爲,算法是數學的內容,學起來特別麻煩。我們不能認爲這種觀點是錯誤的。但是我們也知道,軟件是一種複合的技術,如果一個人只知道算法,但是不能用編程語言很好地實現,那麼再優秀的算法也不能發揮作用。一個人只有有了很好的計算機知識和數學知識,才能在算法的學習上不斷進步。不管算法都麼簡單,都要自己親手實踐,只有不斷認識錯誤、不斷髮現錯誤,才能不斷提高自己的編程能力,不斷提高自己的業務水平。
這裏取名一步一步寫算法的目的主要有兩個:第一,保證我們的算法都是大家可以學得會,看的懂的;第二,保證我們的算法是健壯的、可以測試的。所以在編寫的過程中,我們的算法開發過程是伴隨着測試用例增加的,沒有測試用例保證的代碼只是一段無序的字符而已,沒有什麼價值。
其實任何算法都有自己的應用環境和應用場景,沒有算法可以適用於所有的場景。這一點希望大家明白。同時,我們也要清楚複雜的算法都是由普通的算法構成的,沒有普通的算法就沒有複雜的算法可言,所以複雜變簡單,由大化小,這就是算法分治遞歸的基本思想。

上面的內容我感覺寫的比較好,所以搬運了。下面正式實現自己的版本。
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.博文參考:原文地址,戳我進去

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章