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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

巧用位运算进行排序

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

問題描述如下:

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

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

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

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

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

方法3:使用位運算進行排序

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

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

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

缺點:只適用于不重復(fù)的數(shù)字排序,因為一旦有重復(fù),一個位(bit)為1時,我們沒法知道有多少個重復(fù)的數(shù)字。

核心代碼:

1. 檢測指定字符的指定位的數(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; }

實際案例:

一個文件中有10億條中國地區(qū)的手機號碼,我們要刪除其中重復(fù)的手機號碼

分析如下:

一個手機號碼有11位,優(yōu)化一下,我們認為第一位永遠是1,不予考慮,只需檢測后面的10位數(shù)字

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

按照上面的辦法,以一個位來表示一個數(shù)字,申請一塊10億位(10億bit = 1192M)的數(shù)組

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

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

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

總結(jié)

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

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