在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 數(shù)據(jù)分析&挖掘/ 尋找丟失的數(shù)
hash表
單詞統(tǒng)計(jì)
鏈表排序
查找
可變參數(shù)
爬樓梯
內(nèi)存
prim算法 中
線性結(jié)構(gòu)的處理
數(shù)據(jù)選擇
prim算法 上
循環(huán)單向鏈表
基數(shù)排序
堆排序
鏈表重合
排序二叉樹(shù)的保存和加載
圖添加和刪除
排序二叉樹(shù)線索化
非遞歸排序
字符串查找 下篇
鏈表逆轉(zhuǎn)
函數(shù)堆棧顯示
遞歸和堆棧
二叉樹(shù)深度遍歷
線性隊(duì)列
循環(huán)和遞歸
快速排序
尋找丟失的數(shù)
A*算法
克魯斯卡爾算法 下
排序二叉樹(shù)
大數(shù)計(jì)算
二叉樹(shù)廣度遍歷
prim算法 下
洗牌算法
圖結(jié)構(gòu)
最大公約數(shù)、最小公倍數(shù)
圖創(chuàng)建
雙向鏈表
字符串查找 上篇
尋路
通用算法的編寫(xiě)
哈夫曼樹(shù) 下
線性堆棧
八皇后
排序二叉樹(shù)刪除-1
挑選最大的n個(gè)數(shù)
字符串查找 中篇
哈夫曼樹(shù) 上
合并排序
回?cái)?shù)
選擇排序
哈希二叉樹(shù)
通用數(shù)據(jù)結(jié)構(gòu)
“數(shù)星星”
單向鏈表
排序二叉樹(shù)插入
圖的保存
排序二叉樹(shù)刪除-2
排序二叉樹(shù)刪除-3
n!中末尾零的個(gè)數(shù)統(tǒng)計(jì)

尋找丟失的數(shù)

假設(shè)我們有一個(gè)1億個(gè)數(shù)據(jù),其中數(shù)據(jù)的范圍是0~1億,也就是100M的數(shù)據(jù)。但是這個(gè)數(shù)組中丟了一些數(shù)據(jù),比如說(shuō)少了5啊,少了10啊,那么有什么辦法可以把這些丟失的數(shù)據(jù)找回來(lái)呢?這個(gè)題目不難,但是它可以幫助我們拓展思路,不斷提高算法的運(yùn)行效率。

對(duì)于這個(gè)問(wèn)題,我們一個(gè)最簡(jiǎn)單的思路就是對(duì)各個(gè)數(shù)據(jù)進(jìn)行flag判斷,然后依次輸出數(shù)據(jù)。

void get_lost_number(int data[], int length)  
{  
    int index;  

    assert(NULL != data && 0 != length);  
    unsigned char* pFlag = (unsigned char*)malloc(length * sizeof(unsigned char));  
    memset(pFlag, 0, length * sizeof(unsigned char));  

    for(index = 0; index < length; index ++){  
        if(0 == pFlag[data[index]])  
            pFlag[data[index]] = 1;  
    }  

    for(index = 0; index < length; index++){  
        if(0 == pFlag[index])  
            printf("%d\n", index);  
    }  

    free(pFlag);  
    return;  
}  

可能朋友也看到了,上面的代碼需要分配和原來(lái)數(shù)據(jù)一樣length的空間。其實(shí)我們可以用bit進(jìn)行訪問(wèn)標(biāo)志的設(shè)定,所以我們申請(qǐng)的空間還可以減少。

void get_lost_number(int data[], int length)  
{  
    int index;  

    assert(NULL != data && 0 != length);  
    unsigned char* pFlag = (unsigned char*)malloc((length + 7) >> 3);  
    memset(pFlag, 0, length * sizeof(unsigned char));  

    for(index = 0; index < length; index ++){  
        if(0 == (pFlag[data[index] >> 3] & (1 << (data[index] % 8))))  
            pFlag[data[index] >> 3] |= 1 << (data[index] % 8);  
    }  

    for(index = 0; index < length; index++){  
        if(0 == (pFlag[data[index] >> 3] & (1 << (data[index] % 8))))  
            printf("%d\n", index);  
    }  

    free(pFlag);  
    return;  
}  

上面的代碼已經(jīng)在空間上面有所減小,那么有什么辦法并行運(yùn)算這些數(shù)據(jù)呢?

void get_lost_number(int data[], int length)  
{  
    int index;  
    RANGE range[4] = {0};  

    assert(NULL != data && 0 != length);  
    unsigned char* pFlag = (unsigned char*)malloc((length + 7) >> 3);  
    memset(pFlag, 0, length * sizeof(unsigned char));  

    range[0].start = 0,               range[0].end = length >> 2;  
    range[1].start = length >> 2 ,    range[1].end = length >> 1;  
    range[2].start = length >> 1 ,    range[2].end = length >> 2 * 3;  
    range[3].start = length >> 2 * 3, range[3].end = length;  

#pragma omp parallel for  
    for(index = 0; index < 4; index ++){  
        _get_lost_number(data, range[index].start, range[index].end, pFlag);  
    }  

    for(index = 0; index < length; index++){  
        if(0 == (pFlag[data[index] >> 3] & (1 << (data[index] % 8))))  
            printf("%d\n", index);  
    }  

    free(pFlag);  
    return;  
}  

為了多核的并行計(jì)算,我們添加了子函數(shù)_get_lost,我們進(jìn)一步補(bǔ)充完整。

typedef struct _RANGE  
{  
    int start;  
    int end;  
}RANGE;  

void _get_lost_number(int data[], int start, int end, unsigned char pFlag[])  
{  
    int index;  

    for(index = start; index < end; index++){  
        if(0 == (pFlag[data[index] >> 3] & (1 << (data[index] % 8))))  
            pFlag[data[index] >> 3] |= 1 << (data[index] % 8);  
    }  
}  

工作總結(jié):

(1)代碼的優(yōu)化是可以不斷進(jìn)行得,但是不見(jiàn)得適用于所有的場(chǎng)景

(2)目前的cpu已經(jīng)開(kāi)始從2核->4核->8核轉(zhuǎn)變,朋友們?cè)诳赡艿那闆r下盡量多掌握一些多核編程的知識(shí)。