[838]外排序通用版

前段时间写了一个外排序的程序,但不够通用,这次完善了一下,改成通用的了

就不多介绍了,直接上码

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.IO;
  6 
  7 namespace Cn.Edu.Dlut.Wisdom.Algorithm
  8 {
  9     public class DiskSort<T> where T:IComparable<T>
 10     {
 11         /// <summary>
 12         /// 工作目录
 13         /// </summary>
 14         private string workDir;
 15         /// <summary>
 16         /// 外排序的文件名
 17         /// </summary>
 18         private string fileName;
 19         /// <summary>
 20         /// 数据属性分割符
 21         /// </summary>
 22         private char[] sep;
 23         /// <summary>
 24         /// 排序依赖的属性序号,从0开始
 25         /// </summary>
 26         private int keyIndex;
 27         /// <summary>
 28         /// 最小文件分割大小
 29         /// </summary>
 30         private long minSliptSize;
 31 
 32 
 33         /// <summary>
 34         /// 构造函数/
 35         /// </summary>
 36         /// <param name="workDir">工作目录</param>
 37         /// <param name="fileName">排序的文件名</param>
 38         /// <param name="sep">属性分隔符</param>
 39         /// <param name="keyIndex">排序属性序号</param>
 40         /// <param name="sortType">排序属性类型</param>
 41         /// <param name="minSliptSize">最小文件分割大小</param>
 42         public DiskSort(string workDir, string fileName, char[] sep, int keyIndex, long minSliptSize)
 43         {
 44             this.workDir = workDir;
 45             this.fileName = fileName;
 46             this.sep = sep;
 47             this.keyIndex = keyIndex;
 48             this.minSliptSize = minSliptSize;
 49         }
 50 
 51         public void Sort()
 52         {
 53             MergeSort(fileName);
 54         }
 55 
 56         private void MergeSort(string fileName)
 57         {
 58             if (new FileInfo(workDir + fileName).Length <= minSliptSize) // 内存排序
 59             {
 60                 var lines = File.ReadLines(workDir + fileName);
 61                 List<Pair<T>> pairs = new List<Pair<T>>();
 62                 foreach (string line in lines)
 63                 {
 64                     string[] ls = line.Split(sep);
 65                     T key = (T)ConvertString.ToType(typeof(T), ls[keyIndex]);
 66                     pairs.Add(new Pair<T>(key, line));
 67                 }
 68                 pairs.Sort();
 69                 using (StreamWriter sw = new StreamWriter(workDir + fileName))
 70                 {
 71                     foreach (Pair<T> p in pairs)
 72                     {
 73                         sw.WriteLine(p);
 74                     }
 75                     sw.Flush();
 76                 }
 77             }
 78             else // 硬盘排序
 79             {
 80                 // 分解文件
 81                 string file1 = fileName + "1";
 82                 string file2 = fileName + "2";
 83                 using (StreamReader sr = new StreamReader(workDir + fileName))
 84                 using (StreamWriter sw1 = new StreamWriter(workDir + file1))
 85                 using (StreamWriter sw2 = new StreamWriter(workDir + file2))
 86                 {
 87                     int i = 0;
 88                     while (!sr.EndOfStream)
 89                     {
 90                         string line = sr.ReadLine();
 91                         if (i++ % 2 == 0)
 92                             sw1.WriteLine(line);
 93                         else
 94                             sw2.WriteLine(line);
 95                     }
 96                     sw1.Flush();
 97                     sw2.Flush();
 98                 }
 99                 // 对分解出的文件,分别进行排序
100                 MergeSort(file1);
101                 MergeSort(file2);
102                 // 把两个文件进行合并
103                 using (StreamReader sr1 = new StreamReader(workDir + file1))
104                 using (StreamReader sr2 = new StreamReader(workDir + file2))
105                 using (StreamWriter sw = new StreamWriter(workDir + fileName))
106                 {
107                     string line1 = sr1.ReadLine();
108                     T key1 = (T)ConvertString.ToType(typeof(T), line1.Split(sep)[keyIndex]);
109                     string line2 = sr2.ReadLine();
110                     T key2 = (T)ConvertString.ToType(typeof(T), line2.Split(sep)[keyIndex]);
111                     while (!sr1.EndOfStream || !sr2.EndOfStream)
112                     {
113 
114                         if (key1.CompareTo(key2) <= 0)
115                         {
116                             sw.WriteLine(line1);
117                             if (sr1.EndOfStream)
118                             {
119                                 sw.WriteLine(line2);
120                                 while (!sr2.EndOfStream)
121                                 {
122                                     sw.WriteLine(sr2.ReadLine());
123                                 }
124                             }
125                             else
126                             {
127                                 line1 = sr1.ReadLine();
128                                 key1 = (T)ConvertString.ToType(typeof(T), line1.Split(sep)[keyIndex]);
129                                 if (sr1.EndOfStream && sr2.EndOfStream)
130                                 {
131                                     if (key1.CompareTo(key2) <= 0)
132                                     {
133                                         sw.WriteLine(line1);
134                                         sw.WriteLine(line2);
135                                     }
136                                     else
137                                     {
138                                         sw.WriteLine(line2);
139                                         sw.WriteLine(line1);
140                                     }
141                                 }
142                             }
143                         }
144                         else
145                         {
146                             sw.WriteLine(line2);
147                             if (sr2.EndOfStream)
148                             {
149                                 sw.WriteLine(line1);
150                                 while (!sr1.EndOfStream)
151                                 {
152                                     sw.WriteLine(sr1.ReadLine());
153                                 }
154                             }
155                             else
156                             {
157                                 line2 = sr2.ReadLine();
158                                 key2 = (T)ConvertString.ToType(typeof(T), line2.Split(sep)[keyIndex]);
159                                 if (sr1.EndOfStream && sr2.EndOfStream)
160                                 {
161                                     if (key1.CompareTo(key2) <= 0)
162                                     {
163                                         sw.WriteLine(line1);
164                                         sw.WriteLine(line2);
165                                     }
166                                     else
167                                     {
168                                         sw.WriteLine(line2);
169                                         sw.WriteLine(line1);
170                                     }
171                                 }
172                             }
173                         }
174                     }
175                     sw.Flush();
176                 }
177                 // 删除临时文件
178                 File.Delete(workDir + file1);
179                 File.Delete(workDir + file2);
180             }
181         }
182     }
183 
184     public class Pair<T>:IComparable<Pair<T>> where T:IComparable<T>
185     {
186         /// <summary>
187         /// 建值
188         /// </summary>
189         private T key;
190         /// <summary>
191         /// 字符串值
192         /// </summary>
193         private string all;
194 
195         public Pair(T key, string all)
196         {
197             this.key = key;
198             this.all = all;
199         }
200 
201         /// <summary>
202         /// 根据关键字进行比较
203         /// </summary>
204         /// <param name="other"></param>
205         /// <returns></returns>
206         public int CompareTo(Pair<T> other)
207         {
208             return key.CompareTo(other.key);
209         }
210 
211         public override string ToString()
212         {
213             return all;
214         }
215     }
216 
217     public class ConvertString
218     {
219         public static object ToType(Type type, string value)
220         {
221             return System.ComponentModel.TypeDescriptor.GetConverter(type).ConvertFrom(value);
222         }
223     }
224 }
225 


 

posted on 2010-09-05 17:44  小橋流水  阅读(206)  评论(0编辑  收藏  举报

导航