要求完成文件读取,过滤,列印操作。
有一大小为1GB的源文件mail.log中记录以下格式的数据,将其中信箱为@sina.com的地址筛选出来。
要求程序占用的内存不能超过512MB,代码尽可能高效,在最短时间完成运算。
实际代码或伪代码或者写明思路都可以
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
求高手帮忙,这个是我昨天面试遇到的题目

解决方案 »

  1.   

    $fp = fopen('mail.log', 'r');
    while($buf = fgets($fp)) {
      if(preg_match('/@sina.com/i', $buf))
        echo $buf;
    }
    fclose($fp);
      

  2.   

    1G的文件打开估计都得10几分钟,打开是无法避免的
    还有读入内存的话512肯定不够存储
    所以只能象1楼一样,循环读取
    但是用正则肯定不行,因为正则的效率是非常低的,当数据是1万行左右差别不是很大,但是超过这个,数量大的话是非常慢的,不行你们可以自己模拟。所以建议将
    if(preg_match('/@sina.com/i', $buf))
    改成if(substr("@sina.com","",$buf)!=$buf)
    大家可以用这两个来测试一下速度。
      

  3.   

    老大那个就可以满足要求了。fgets一次只读取文件一行。文件的一行不可能超过512MB,正常来说是80字节。
    这样读一行正则match '\w+@sina\.com'一次,有的话就写入文件。这题要你避免的是一次性把整个文件都读出来再去正则匹配。比如$str = file_get_contents('./mail.log');再去匹配$str这样就把1G内容全装内存里了。实际应用的话,也就这样了。如果再想讲究下模式匹配算法的话。posix的正则算法我还真不清楚用的是什么。kmp,bm你可以去看看这些算法。对于内容中子模式重复过高的情况,kmp和bm的效率比较高。
      

  4.   

    回13楼strpos在英文下查找是没有什么问题,但是有汉字就偶尔抽筋。
    实现一个功能有很多的方法
    比如正则,查找
    那我用的方法是把你要找的字符替换成空,再对比两个字符串,如果不一样说明存在被替换了。
    所以思考问题请大家不要局限在某一个方面。
      

  5.   

    学习了一楼的思路 不错,这个让我写的话 我就知道个file_get_contents
      

  6.   


    function getEmail($file, $str) {
    $arrRs = array();
    $rs = fopen($file,'r+');
    while (!feof($rs)) {
    $email = fgets($rs, 4096);
    if(stristr($email, $str))
    $arrRs[] = $email;
    }
    return $arrRs;
            fclose($rs);
    }echo getEmail('mail.log', '@sina.com');
      

  7.   


    function   getEmail($file,   $str)   { 
    $arrRs   =   array(); 
    $rs   =   fopen($file, 'r+ '); 
    while   (!feof($rs))   { 
    $email   =   fgets($rs,   4096); 
    if(stristr($email,   $str)) 
    $arrRs[]   =   $email; 

    return   $arrRs; 
                    fclose($rs); 
    } echo   getEmail( 'mail.log ',   '@sina.com '); 
      

  8.   

    function getEmail($file, $str) {
    $arrRs = array();
    $rs = fopen($file,'r+');
    while (!feof($rs)) {
    $email = fgets($rs, 4096);
    if(stristr($email, $str))
    $arrRs[] = $email;
    }
    fclose($rs);
    return $arrRs;
    }
    var_dump(getEmail('test.log', '@sina.com')) ;