前段時間看到“100G的大檔案中找出最大的100個數"。所以寫下這篇文章。
轉載請註明出處 作者: 黎承湘
要求 : 有一個100G大小的檔案裡存的全是數字,並且每個數字見用逗號隔開。現在在這一大堆數字中找出100個最大的數出來。
源貼http://topic.csdn.net/u/20091013/10/d5d371dc-6dec-4034-bf31-432a47ffce96.html
說明:重在方法,所以沒有用100G的資料來進行測試。
目的:寫完代碼。分別用,小於1G,1G,1.5G ,2G,2.5G的資料進行測試,發現速度太慢。特發此貼,求更優秀的代碼。請各位朋友,不要紙上談兵。一切以資料說話。
代碼: static void Main(string[] args)<br /> {<br /> string path = "data.txt";<br /> //產生100G檔案<br /> //write(path,100000000);<br /> //計算程式已耗用時間<br /> Stopwatch stop = new Stopwatch();<br /> stop.Start();<br /> string[] MaxData = new string[100]; //初始化100個最大數的容器<br /> for (int i = 0; i < 100; i++)<br /> MaxData[i] = "0";<br /> int nBytes = 1024 * 1024 * 512; //每次讀取0.5G資料進行處理<br /> byte[] data = new byte[nBytes];<br /> FileInfo fi = new FileInfo(path);<br /> FileStream fs = fi.OpenRead();<br /> int l = fs.Read(data, 0, nBytes);<br /> string strData = "";<br /> while (l > 0)<br /> {<br /> for (int i = 0; i < l; i++)<br /> {<br /> if (data[i] == 44) //遇到","分隔字元<br /> {<br /> if (strData != "")<br /> Compare(strData, ref MaxData);<br /> strData = "";<br /> }<br /> else<br /> strData += stringData(data[i]);<br /> }<br /> l = fs.Read(data, 0, nBytes);<br /> }<br /> stop.Stop();<br /> Console.WriteLine(stop.ElapsedMilliseconds.ToString());<br /> Console.Read();<br /> //把結果儲存起來<br /> foreach (string str in MaxData)<br /> WriteLineText("result.txt", str);<br /> }<br /> /// <summary><br /> /// 轉為數字<br /> /// </summary><br /> /// <param name="data">每個二進數</param><br /> /// <returns>還回10進位數</returns><br /> static string stringData(int data)<br /> {<br /> int strdata = data - 48;<br /> return strdata.ToString();<br /> }<br /> /// <summary><br /> /// 跟最大的100個數中的最小數進行比較<br /> /// </summary><br /> /// <param name="data">新讀取的數</param><br /> /// <param name="MaxData">最大的100個數</param><br /> static void Compare(string data ,ref string[] MaxData)<br /> {<br /> if (data.Length < MaxData[99].Length) return;<br /> else if (data.Length > MaxData[99].Length) { MaxData[99] = data; SortData(ref MaxData); }<br /> else<br /> {<br /> for (int i = 0 ; i < data.Length ; i++)<br /> {<br /> if (int.Parse(data[i].ToString()) > int.Parse(MaxData[99][i].ToString())) { MaxData[99] = data; SortData(ref MaxData); break; }<br /> else if (int.Parse(data[i].ToString()) < int.Parse(MaxData[99][i].ToString())) break;<br /> }<br /> }<br /> }<br /> /// <summary><br /> /// 排序<br /> /// </summary><br /> /// <param name="MaxData">儲存最大的100個數</param><br /> static void SortData(ref string[] MaxData)<br /> {<br /> int maxID = 99; //記錄比MaxData[99]大的最小數的位置<br /> for (int i = 98; i > -1; i--)<br /> {<br /> if (MaxData[i].Length > MaxData[99].Length) { maxID = i + 1; break; }<br /> else if (MaxData[i].Length == MaxData[99].Length)<br /> {<br /> bool ismax = true ; //MaxData[99]小<br /> for (int j = 0; j < MaxData[99].Length; j++)<br /> {<br /> if (int.Parse(MaxData[i][j].ToString()) > int.Parse(MaxData[99][j].ToString())) { ismax = true ; break; }<br /> else if (int.Parse(MaxData[i][j].ToString()) < int.Parse(MaxData[99][j].ToString())) { ismax = false; break; }<br /> }<br /> if (ismax)<br /> {<br /> maxID = i+1;<br /> break;<br /> }<br /> }<br /> maxID = i;<br /> }<br /> string data = MaxData[99];<br /> for (int i = 99; i > maxID; i--)<br /> {<br /> MaxData[i] = MaxData[i - 1];<br /> }<br /> MaxData[maxID] = data;<br /> }<br /> /// <summary><br /> /// 寫資料(每一個數都是隨機產生,長度為(1-100)<br /> /// </summary><br /> /// <param name="path">寫資料的路徑</param><br /> /// <param name="n">需要寫多少個數</param><br /> static void write(string path , int n)<br /> {<br /> WriteText(path, "0");</p><p> Random rlength = new Random();<br /> Random rdata = new Random(); //<br /> for (int i = 0; i < n; i++) //產生N個隨機數<br /> {<br /> int length = rlength.Next(1, 100); //產生一個位元(1-100)的數字<br /> string strdata = ",";<br /> for (int j = 0; j < length; j++)<br /> {<br /> if (j == 0 && length > 1) strdata += rdata.Next(1, 9).ToString(); //如果位元>1那麼首數字不能為零<br /> else<br /> strdata += rdata.Next(0, 9).ToString();<br /> }<br /> WriteText(path, strdata);<br /> }<br /> }<br /> static void WriteText(string path, string text)<br /> {<br /> using (StreamWriter write = new StreamWriter(path, true, Encoding.Default))<br /> {<br /> write.Write(text);<br /> }<br /> }<br /> /// <summary><br /> /// 儲存最大的100個數<br /> /// </summary><br /> /// <param name="path">儲存的路徑</param><br /> /// <param name="text">數字</param><br /> static void WriteLineText(string path, string data)<br /> {<br /> using (StreamWriter write = new StreamWriter(path, true, Encoding.Default))<br /> {<br /> write.WriteLine(data);<br /> }<br /> }