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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

公司的一道考试题算法分析——大数据量整数排序

發布時間:2024/9/20 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 公司的一道考试题算法分析——大数据量整数排序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目大意:移動公司需要對已經發放的所有139段的號碼進行統計排序,已經發放的139號碼段的文件都存放在一個文本文件中(原題是放在兩個文件中),一個號碼一行,現在需要將文件里的所有號碼進行排序,并寫入到一個新的文件中;號碼可能會有很多,最多可能有一億個不同的號碼(所有的139段號碼),存入文本文件中大概要占1.2G的空間;jvm最大的內存在300以內,程序要考慮程序的可執行性及效率;只能使用Java標準庫,不得使用第三方工具。?
??? 這是個典型的大數據量的排序算法問題,首先要考慮空間問題,一下把1.2G的數據讀入內存是不太可能的,就算把1一億條數據,轉都轉換成int類型存儲也要占接近400M的空間。當時做個題目我并沒有想太多的執行效率問題,主要就考慮了空間,而且習慣性的想到合并排序,基本思想是原文件分割成若干個小文件并排序,再將排序好的小文件合并得到最后結果,算法大概如下:?

??? 1.順序讀取存放號碼文件的中所有號碼,并取139之后的八位轉換為int類型;每讀取號碼數滿一百萬個(這個數據可配置)將已經讀取的號碼排序并存入新建的臨時文件。?
??? 2.將所有生成的號碼有序的臨時文件合并存入結果文件。
?

??? 這個算法雖然解決了空間問題,但是運行效率極低,由于IO讀寫操作太多,加上步驟1中的排序的算法(快速排序)本來效率就不高(對于電話排序這種特殊情況來說),導致1億條數據排序運行3個小時才有結果。?

??? 如果和能夠減少排序的時間呢?首當其沖的減少IO操作,另外如果能夠有更加好排序算法也行。前天無聊再看這個題目時突然想到大三時看《編程珠璣》時上面也有個問題的需求這個這個題目差不多,記得好像使用是位向量(實際上就是一個bit數組),用電話作為index,心中大喜,找到了解決此問題的最完美方案啦:用位向量存儲電話號碼,一個號碼占一個bit,一億個電話號碼也只需要大概12M的空間;算法大概如下:?
????? 1.初始化bits[capacity];?
????? 2.順序所有讀入電話號碼,并轉換為int類型,修改位向量值:bits[phoneNum]=1;?
????? 3.遍歷bits數組,如果bits[index]=1,轉換index為電話號碼輸出。
?
??? Java中沒有bit類型,一個boolean值占空間為1byte(感興趣的可以自己寫程序驗證),我自己寫個個用int模擬bit數組的類,代碼如下:?
???

Java代碼??
  • public?class?BitArray?{??
  • ????private?int[]?bits?=?null;??
  • ????private?int?length;??
  • ????//用于設置或者提取int類型的數據的某一位(bit)的值時使用??
  • ????private?final?static?int[]?bitValue?=?{??
  • ????????0x80000000,//10000000?00000000?00000000?00000000????????
  • ????????0x40000000,//01000000?00000000?00000000?00000000????????
  • ????????0x20000000,//00100000?00000000?00000000?00000000????????
  • ????????0x10000000,//00010000?00000000?00000000?00000000????????
  • ????????0x08000000,//00001000?00000000?00000000?00000000????????
  • ????????0x04000000,//00000100?00000000?00000000?00000000????????
  • ????????0x02000000,//00000010?00000000?00000000?00000000????????
  • ????????0x01000000,//00000001?00000000?00000000?00000000????????
  • ????????0x00800000,//00000000?10000000?00000000?00000000????????
  • ????????0x00400000,//00000000?01000000?00000000?00000000????????
  • ????????0x00200000,//00000000?00100000?00000000?00000000????????
  • ????????0x00100000,//00000000?00010000?00000000?00000000????????
  • ????????0x00080000,//00000000?00001000?00000000?00000000????????
  • ????????0x00040000,//00000000?00000100?00000000?00000000????????
  • ????????0x00020000,//00000000?00000010?00000000?00000000????????
  • ????????0x00010000,//00000000?00000001?00000000?00000000????????????
  • ????????0x00008000,//00000000?00000000?10000000?00000000????????
  • ????????0x00004000,//00000000?00000000?01000000?00000000????????
  • ????????0x00002000,//00000000?00000000?00100000?00000000????????
  • ????????0x00001000,//00000000?00000000?00010000?00000000????????
  • ????????0x00000800,//00000000?00000000?00001000?00000000????????
  • ????????0x00000400,//00000000?00000000?00000100?00000000????????
  • ????????0x00000200,//00000000?00000000?00000010?00000000????????
  • ????????0x00000100,//00000000?00000000?00000001?00000000????????
  • ????????0x00000080,//00000000?00000000?00000000?10000000????????
  • ????????0x00000040,//00000000?00000000?00000000?01000000????????
  • ????????0x00000020,//00000000?00000000?00000000?00100000????????
  • ????????0x00000010,//00000000?00000000?00000000?00010000????????
  • ????????0x00000008,//00000000?00000000?00000000?00001000????????
  • ????????0x00000004,//00000000?00000000?00000000?00000100????????
  • ????????0x00000002,//00000000?00000000?00000000?00000010????????
  • ????????0x00000001?//00000000?00000000?00000000?00000001??????????????
  • ????};??
  • ????public?BitArray(int?length)?{??
  • ????????if(length?<?0){??
  • ????????????throw?new?IllegalArgumentException("length必須大于零!");??
  • ????????}??
  • ????????bits?=?new?int[length?/?32?+?(length?%?32?>?0???1?:?0)];??
  • ????????this.length?=?length;??
  • ????}??
  • ????//取index位的值??
  • ????public?int?getBit(int?index){??
  • ????????if(index?<0?||?index?>?length){??
  • ????????????throw?new?IllegalArgumentException("length必須大于零小于"?+?length);??
  • ????????}??
  • ????????int?intData?=?bits[index/32];??
  • ????????return?(intData?&?bitValue[index%32])?>>>?(32?-?index%32?-1);??
  • ????}??
  • ????//設置index位的值,只能為0或者1??
  • ????public?void?setBit(int?index,int?value){??
  • ????????if(index?<0?||?index?>?length){??
  • ????????????throw?new?IllegalArgumentException("length必須大于零小于"?+?length);??
  • ????????}?????????
  • ????????if(value!=1&&value!=0){??
  • ????????????throw?new?IllegalArgumentException("value必須為0或者1");??
  • ????????}??
  • ????????int?intData?=?bits[index/32];??
  • ????????if(value?==?1){??
  • ????????????bits[index/32]?=?intData?|?bitValue[index%32];??
  • ????????}else{??
  • ????????????bits[index/32]?=?intData?&?~bitValue[index%32];??
  • ????????}??
  • ????}??
  • ????public?int?getLength(){??
  • ????????return?length;??
  • ????}?????
  • }??????
  • ??????

  • ????
    ??? bit數組有了,剩下就是算法代碼,核心代碼如下:?
    ??? Java代碼??
  • bitArray?=?new?BitArray(100000000);???
  • //順序讀取所有的手機號碼??
  • while((phoneNum?=?bufferedReader.readLine())!=null){??
  • ????phoneNum?=?phoneNum.trim().substring(3);//13573228432??
  • ????//取139后8位轉換為int類型??
  • ????phoneNumAsInt?=?Integer.valueOf(phoneNum);??
  • ????//設置對應bit值為1??
  • ????bitArray.setBit(phoneNumAsInt,?1);??
  • }?????
  • //遍歷bit數組輸出所有存在的號碼??
  • for(int?i?=?0;i<sortUnit;i++){??
  • ????if(bitArray.getBit(i)==1){??
  • ????????????writer.write("139"?+?leftPad(String.valueOf(i?+?sortUnit*times),?8));??
  • ????????????writer.newLine();?????????????????????????
  • ????}?????????????????
  • }??
  • writer.flush();??
  • ???

  • ??? 經測試,修改后的算法排序時只需要20多M的內存,一億條電話號碼排序只要10分鐘(時間主要花在IO上),看來效果還是很明顯的。?
    ??? 這個算法很快,不過也有他的局限性:?
    ??? 1.只能用于整數的排序,或者可以準確映射到正整數(對象不同對應的正整數也不相同)的數據的排序。?
    ??? 2.不能處理重復的數據,重復的數據排序后只有一條(如果有這種需求可以在這個算法的基礎上修改, 給出現次數大于1的數據添加個計數器 ,然后存入Map中)?
    ??? 3.對于數據量極其大的數據處理可能還是比較占用空間, 這種情況可配合多通道排序算法解決。 ?

    ??? PS:這個算法的思想源于《編程珠璣》,有興趣的可以讀讀那本書,非常不錯!

    來源:http://pisces-java.iteye.com/blog/766745

    總結

    以上是生活随笔為你收集整理的公司的一道考试题算法分析——大数据量整数排序的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。