日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

巧用位运算进行排序

發(fā)布時(shí)間:2024/2/28 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 巧用位运算进行排序 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

問(wèn)題描述如下:

一個(gè)4G內(nèi)存的系統(tǒng),一個(gè)文件存儲(chǔ)了9億條不重復(fù)的9位數(shù),現(xiàn)在要對(duì)這個(gè)文件進(jìn)行排序

方法1:內(nèi)存中進(jìn)行排序(快速排序,插入排序,堆排序,歸并排序等)

我們來(lái)分析下,9位數(shù)需要用int或者unsigned int類(lèi)型來(lái)表示,4個(gè)字節(jié),9億 * 4字節(jié)= 36億字節(jié) =?3433M內(nèi)存,對(duì)于4G內(nèi)存的系統(tǒng),訪問(wèn)3.4G的內(nèi)存,難度很大,因?yàn)檫@種方法行不通

方法2:在數(shù)據(jù)庫(kù)中進(jìn)行排序

只需要讀取文件后導(dǎo)入數(shù)據(jù)庫(kù),進(jìn)行排序即可。缺點(diǎn):要有數(shù)據(jù)庫(kù)等設(shè)備

方法3:使用位運(yùn)算進(jìn)行排序

9位數(shù)的范圍也就是0-999999999,一共10億個(gè)數(shù)字,如果我們?yōu)槊恳粋€(gè)數(shù)字用一個(gè)位(bit)來(lái)表示存在還是不存在,一共只需要10億位= 1.25億字節(jié) = 119M,這樣很容易申請(qǐng)內(nèi)存。

具體辦法:申請(qǐng)一塊10億位(1.25億字節(jié))的數(shù)組,全部初始化為0。依次讀取文件中的數(shù)字,把該數(shù)字對(duì)應(yīng)的位上標(biāo)記為1表示已存在。比如數(shù)字987654321,在內(nèi)存中移位到987654321對(duì)應(yīng)的位,設(shè)置為1。最后,從低位到高位(或從高位到低位)遍歷整個(gè)數(shù)組,為1的說(shuō)明存在該數(shù),寫(xiě)入到文件中即可

優(yōu)點(diǎn):我們用一個(gè)位(bit)來(lái)表示一個(gè)9位數(shù),而不是一個(gè)int(32bit),這樣數(shù)據(jù)量壓縮了32倍

缺點(diǎn):只適用于不重復(fù)的數(shù)字排序,因?yàn)橐坏┯兄貜?fù),一個(gè)位(bit)為1時(shí),我們沒(méi)法知道有多少個(gè)重復(fù)的數(shù)字。

核心代碼:

1. 檢測(cè)指定字符的指定位的數(shù)是否為1

// 判斷字符dest的第second位是否為1 bool IsOne (unsigned char dest, int second) {const static int mark[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};if (second>=8 || second <0) {return false;}return (dest & mark[second]) == mark[second];}

2. 將指定字符的指定位的數(shù)置為1

// 將字符dest的第second位改為1 bool SetOne (unsigned char* dest, int second) {const static int mark[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};if (second>=8 || second <0) {return false;}*dest |= mark[second];return true; }

實(shí)際案例:

一個(gè)文件中有10億條中國(guó)地區(qū)的手機(jī)號(hào)碼,我們要?jiǎng)h除其中重復(fù)的手機(jī)號(hào)碼

分析如下:

一個(gè)手機(jī)號(hào)碼有11位,優(yōu)化一下,我們認(rèn)為第一位永遠(yuǎn)是1,不予考慮,只需檢測(cè)后面的10位數(shù)字

10位數(shù)字的范圍是0-9999999999,一共100億個(gè)數(shù)字

按照上面的辦法,以一個(gè)位來(lái)表示一個(gè)數(shù)字,申請(qǐng)一塊10億位(10億bit = 1192M)的數(shù)組

依次讀取文件,處理某個(gè)數(shù)字時(shí),如果對(duì)應(yīng)位置為0則標(biāo)記為1;如果對(duì)應(yīng)位置為1則說(shuō)明數(shù)字重復(fù),不需處理

注意:由于操作系統(tǒng)或者編程語(yǔ)言本身的限制,有可能系統(tǒng)內(nèi)存足夠,仍然無(wú)法分配一塊連續(xù)大內(nèi)存的情況,這樣的話可以申請(qǐng)多塊稍微小一點(diǎn)的內(nèi)存,然后用鏈表或其他的方式連接起來(lái)使用,只是判斷或者標(biāo)記的時(shí)候需要計(jì)算一下具體的位置

超強(qiáng)干貨來(lái)襲 云風(fēng)專(zhuān)訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生

總結(jié)

以上是生活随笔為你收集整理的巧用位运算进行排序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。