php大文件搜索问题

这个问题还需要再具体一点,就是,

  1. 内存有限,不可能完全把大文本全部读入。
  2. 速度不能过慢。
  3. 题目:有两个文本文件,一个是结果文件,一个是注释文件,每个文件内每行存贮的都是以tab为间隔的数据,而其中tab数都是一致的。也就是说,文本文件可以看成是以tab为间隔的csv文件。每个文件内的第一列(以tab为分隔)都是一个不重复的关键字。要求将两个文本文件以关键字为基准合并起来。

我的思路是:

  1. 将注释文件建立索引
  2. 逐行读取结果文件并注释。

有人说,可以先对两个文件排序,然后再合并。这个方案我也考虑过,但是觉着不如前面的这个思路好。这只是个思路,算不上算法,所以只能说勉强可以完成要求。

#getIndex(),by jianhong from qiuworld.com
#建立索引数组,
#array的key是文本中第一列的关键字,
#value是文本文件距文件起始位置的偏移地址。
function getIndex($ifh,$delimiter){
	$res = fopen($ifh, 'r') or die("can not open $ifh");
	$res_index=array();
	$pos=0;
	while(($line=fgetcsv($res,4096,$delimiter))!==false){
		$res_index[$line[0]]=$pos;
		$pos=ftell($res);
	}
	fclose($res);
	return $res_index;
}
#合并结果文件与注释文件
function getAnnotation($ifh,$afh,$ofh,$delimiter){
	$ann_index=getIndex($afh,$delimiter);
	$res = fopen($ifh, 'r') or die("can not open $ifh");
	$ann = fopen($afh, 'r') or die("can not open $afh");
	$merged = fopen($ofh, 'w') or die("can not open $ofh");
	#合并表头
	$line1=fgets($res);
	$line2=fgets($ann);
	fputs($merged,chop($line1).$delimiter.$line2);
	#合并内容
	while(($line1=fgetcsv($res))!==false){
		if(isset($ann_index[$line1[0]])){
			fseek($ann, $ann_index[$line1[0]]);
			if(($line2=fgetcsv($ann,4096,$delimiter))!==false) fputcsv($merged,array_merge($line1,$line2),$delimiter);
			else fputcsv($merged,$line1,$delimiter);
		}
		else fputcsv($merged,$line1,$delimiter);
	}
	fclose($res);
	fclose($ann);
	fclose($merged);
}
#调用
getAnnotation("results.file.name","annotation.file.name","output.file.name","\t");

发表评论

电子邮件地址不会被公开。 必填项已用*标注