字符串大文件的排序

最近在做字符串的保序压缩编码,由于暂时找不到合适的方式,采用了最笨的方式,对字符串进行排序再采用压缩编码。由于字符串数目巨大,一次性全部至于内存中就会出现段错误。

我们常常说大文件的排序一般都是采用划分、内部排序再归并的方式,道理听过千遍,甚至烂熟于心,却依然在实现的过程中碰到很多问题。在已有系统中,师兄曾实现过定长ID大文件的排序,一开始,我也只是依葫芦画瓢,以为随便改改就可以,不想却遇到了很多问题。

首先,不定长的字符串若是连续的存储在文件中,则各个字符串之间没有明显的分隔,在归并阶段分不清字符串的界限。若一行存储一个字符串,而某些字符串本身又含有换行符或者空格;直接处理字符串的排序就成了大量字符串排序实现的阻碍,而实现更加通用、性能更优的排序就更加困难。

在从原始数据集文件中获得全部即将要排序的字符串之前,需要进行字符串的提取,在这这步操作中,我预先将每个字符串中的换行符用’\t’代替,然后再写入将要排序的文件中,每个字符串尾部加入换行符,形成一个大文件。

文件的内部排序一般来说实现都比较简单,但对文件的读写却也是文件外部排序的一道瓶颈,所以这里我自己设计了临时文件TempFile类,在里面增加文件缓冲为4kps:一般刚好为文件系统一页的大小),减少写的次数,提升部分性能。

代码的实现难点主要在归并阶段,若采用二路归并,则需要迭代的进行二路归并,所以我这里选择了k路归并,并采用优先队列,更方便的实现了归并部分。一开始只针对字符串,故对于要排序的数据类型也就固定了string类型,后来又为了实现的更通用一些,利用了模板类来实现。由于比较字符串大小是将其取到内存中后再比较,对字符串的大小可以用strlen函数来实现,针对其他类型的只能用sizeof,这里还没找到好的方式来统一,如果大家有合适的方法敬请告知,代码已传到github上,代码地址见:https://github.com/wonderfry/kway_sortfile欢迎阅读修改,提出意见。

 

posted @ 2015-06-07 16:44  小龙吃小鱼  阅读(424)  评论(0编辑  收藏  举报