http://blog.csdn.net/shadowsniper/article/details/5750580

来源:互联网 发布:网络招商推广语言 编辑:程序博客网 时间:2024/05/17 08:40

1、我们碰到了大麻烦,一个新来的传教士惹恼了上帝,上帝很愤怒,要求我们把圣经(bbe.txt)背熟,直至他说哪个单词,我们就要飞快的回答出这个单词在第几行第几个单词位置。听说你是个优秀的程序员,那么髟助我们完成这个不可能的任务吧。
  要求如下:
  1)/myworks/example/bbe.txt,98版本英文圣经一本
  2)输入部分要求如下:php ./example.php [单词]
  3)输出部分如下:[单词] 1,2 2,4 5,6 表示:此单词在1行2列(第二个单词),2行4列...
  说明:
  1)此文本4MB之巨...
  2)单词的含义:由英文字母(大小写),数字(0-9)组成的串
  3)提供给你的机器OS为ubuntu 9.10,内存只有1G,而且,很不幸的,其中700M用来做了别的
  4)上机考试不允许上网,但我装了man文档以及读取CHM以及PDF的阅读器,在电脑的桌面的CHM文件夹中,有相应的PHP参考手册
  5)算法复杂度要求不能大于O(N^2)(就是N的平方)
  6)什么?PHP低效且用起来不顺手,好的,你可以用别的语言来实现。但注意:提供给你的机器上只有python 2.4/perl 5.8/gcc[g++] 4.1

 

 

 

最后一道题,我用了建文件索引的方法,似乎也没违反题的规则,关于索引那里,还可以继续深入优化。

<?php/* 此文件用于根据bbe.txt文件对所有单词创建索引,相当于一次预处理 */ini_set('display_errors','on');set_time_limit(0);//行号$row = 1;//单词计数$space = 0;//单词 $str = '';//单词数组$strs = array();$fp = fopen('./bbe.txt','r');//读取bbe.txt文件while(!feof($fp)){ //每次读1字节 while($ch = fread($fp,1)){ //如果读到的是换行,换行计数加1 if( $ch == "/n" || $ch == "/r/n" ){ $row++; $space=0; } //如果读到的是空格,单词计数加1,并且把这个单词按照单词名放进hash,值为行,列。 elseif( $ch == " " || $ch == "/n" || $ch == "/r/n" ){ $space++; $str = strtolower($str); if(!isset($strs[$str])) $strs[$str] = ''; $strs[$str] .= ' '.$row.','.$space; $str = ''; } //ascII范围不在A-Z或a-z之间的丢弃 elseif((ord($ch) < 65 || ord($ch) > 90) && (ord($ch) < 97 || ord($ch) > 122)){ //echo $ch; continue; } else{ $str .= $ch; } }}fclose($fp);//处理hashforeach($strs as $sk => $sv){ $fc = strtolower(substr($sk,0,1)); $nstrs[$fc][$sk] = $sv;}//排序并写入文件散列foreach($nstrs as $ns => $nv){ $nstrs[$ns] = $nv; file_put_contents('./indexs/'.$ns.'.txt',serialize($nstrs[$ns]),FILE_APPEND);}die('索引创建完毕!');



<?php/* 此文件用来查询单词,调用格式为http://url/searchStr.php?searchKey=mysql */$key = strtolower($_GET['searchKey']);$fc = strtolower(substr($key,0,1));$arrayVal = unserialize(file_get_contents('./indexs/'.$fc.'.txt'));isset($arrayVal[$key])?print($key.'的位置序列:'.$arrayVal[$key]):print('没有找到此单词!');?>




其实4MB的文本真不大,读进来直接在内存里处理也绰绰有余,不过内存不能永久性复用,所以我还是放在文件里了。

0 0
原创粉丝点击