2014年1月26日 星期日

005 整數陣列搜尋大法 (參考解)

  回應的人太多了,就如同我當年的仰慕者可以從總統府排隊排到西門町那樣的多,篇幅有限,以下僅列出前四大回應
1. 拼錯字:WARM,WARN傻傻分不清
2. 沒寫註解
3. Code很臭,斷行縮排不照規矩
4. 變數命名不依照團隊編碼規範
科科,Code Review這樣就結束了?所以,你也滿意了嗎?真有那麼簡單,我還需要特別寫一篇網誌來屁嗎?


  先給個修改完然後可以動的版本:

int binarySearch_int(int target[], int toFind, int isize)
{
    if (NULL == target) { return -1; }

    int ileft = 0; int iright = isize-1;
    while(ileft <= iright) // i made mistake here (ileft < iright)
    {
        int imid_index = (iright + ileft) / 2;
        if (target[imid_index] > toFind)
        {
            iright = imid_index - 1;
        }
        else if (target[imid_index] < toFind)
        {
            ileft = imid_index +1;
        }
        else { return imid_index; }
    }
    return -1;
}

int binarySearch_int_R(int target[], int toFind, int ileft, int iright)
{
    if (NULL == target || ileft > iright) { return -1; }

    int imid = (ileft + iright) / 2;
    switch( compare_int(toFind,target[imid]) )
    {
        case 0: // toFind == middle, return middle
        { return imid; } // break;
        case 1: // toFind > middle
        {
            return binarySearch_int_R(target,
                                      toFind,
                                      imid+1,
                                      iright);
        }
        case -1: // toFind < middle
        {
            return binarySearch_int_R(target,
                                      toFind,
                                      ileft,
                                      imid-1);
        }
        default:
        { fprintf(stderr, "WARN: unexpected on compare_int()\n"); } break;
    }
    return -1;
}

耶,好像跟Code Review的建議完全沒關係,那,這些錯誤修正是怎麼發現的?

  其實,哥靠的不是review,是測試!註1

寫測試,跑跑看
 修正後
結案

  話說,如果你是同事A的同事,你參與了這場Code Review饗宴,然後發現你給予的建議完全無助於找出同事A扣裡藏著的真正致命的危機,你的感想是?請你不要再迷戀哥,喔哥只是傳說 註2
「靠么,這種沒做過單元測試的Code,你也好意思拿出來要大家幫忙Review?你是當大家吃飽撐著沒事做嗎?」

  所以,要讓自己不成為靠么星人的最好方法,就是替自己的扣寫測試,可以從成本最低的main開始著手

int main(int argc, char** argv)
{
    int target[]    = { 10, 8, 6, 4, 2, 1, 3, 5, 7, 9};
    uint32_t uisize = sizeof(target) / sizeof(int);
    selectionSort_int(target, (sizeof(target)/sizeof(int)));
    printf("target array = [");
    for(int i=0; i< int(uisize); i++)
    { printf(" %d", target[i]); }
    printf(" ]\n");

    int toFind    = 0;
    int iexpected = 0;
    int iResult   = 0;
    // testing if-fount
    for(uint32_t i=0; i<uisize; i++)
    {
        printf("\nFAST: Testing Run [%d]\n", i+1);
        toFind = target[i];
        iexpected = i;
        iResult = binarySearch_int(target, toFind, uisize);
        printf("\t%s binarySearch_int(%d)\n",
               iexpected == iResult?"pass":"fail",
               iResult);

        iResult = binarySearch_int_R(target, toFind, 0, uisize);
        printf("\t%s binarySearch_int_R(%d)\n",
               iexpected == iResult?"pass":"fail",
               iResult);
    }
    // test if-not-found
    {
        toFind = 11; iexpected = -1;
        printf("\nFET: Test not-found [%d]\n", toFind);
        iResult = binarySearch_int(target, toFind, uisize);
        printf("\t%s binarySearch_int(%d)\n",
               iexpected == iResult?"pass":"fail",
               iResult);
        iResult = binarySearch_int_R(target, toFind, 0, uisize);
        printf("\t%s binarySearch_int_R(%d)\n",
               iexpected == iResult?"pass":"fail",
               iResult);
    }
    // test if-not-found
    {
        toFind = 0; iexpected = -1;
        printf("\nFET: Test not-found [%d]\n", toFind);
        iResult = binarySearch_int(target, toFind, uisize);
        printf("\t%s binarySearch_int(%d)\n",
               iexpected == iResult?"pass":"fail",
               iResult);
        iResult = binarySearch_int_R(target, toFind, 0, uisize);
        printf("\t%s binarySearch_int_R(%d)\n",
               iexpected == iResult?"pass":"fail",
               iResult);
    }
    return 0;
}

  然後,漸漸地,你會發現捏麵(neo-main)人不好做,然後試著Google一下,就會發現,有種工具叫做xUnit,譬如說 CppUnit或googletest,這類好用的單元測試框架unit test framework,以及,有種寫扣方式叫做測試先行Test Driven Development;之後,你會發現,世界真的不一樣,只寫扣不應酬的工程師也可以準時下班


註1「哥吃的不是麵,是寂寞」開啟了一系列的照樣照句.
註2「哥只是個傳說 」 http://www.youtube.com/watch?v=vXhyLjxzt4U

沒有留言:

張貼留言