请编写PHP代码对数据文件(data)进行操作,尝试完成以下几个任务:

删除不足12位的行、重复行
按CNAPS号校验算法删除错误数据行 (双模效验 )
按substr(line,0,3)与substr(line,3,4)双条件正序对数据集进行排序
保存数据集至用户根目录,文件名为其的SHA1值
在代码最后一行调用memory_get_peak_usage(false),并将返回值转换为kb输出

PS:
数据文件换行符为\n
PHP的内存已被限制为64M,不得调高内存限制

下载data文件 下载 (当图片上传了 下载后命名为: data.xz)

<?php

/**
 * 执行效果
    win10  CPU:i7  PHP 5.6 
    time:30 second  (29-32秒之间)
    Memcache max: 41.328315734863 M
 */


class data{
    
    private $set = [];
    
    public function filter($file='data')
    {
        $f = fopen($file,"r");
        if($f){
           while (!feof($f))
            {
                $line = trim(fgets($f)); //去掉 \n
            
                if(self::length($line) && self::cnaps($line)) // 长度 和 双模验证
                {
                    $key = (int)substr($line,0,3);
                    $this->set[$key][$line] = null ; // 去重
                }
            }
            fclose($f);
        }
    }
    
    public static function length($str)
    {
        if(strlen($str) < 12)
        {
            return false;
        }
        return true;
    }
    
    public static function cnaps($str)
    {
        $count = strlen($str);
        $p = 10;
        for($i=0;$i<$count-1;$i++)
        {
            $number = (int)$str[$i];
            $p = (($n=($p+$number)%10)?:10)*2%11;
        }
        if($p<2){
            $p=1-$p;
        }else{
            $p=11-$p;
        }
        return $p==$str[$count-1];
    }
    
    public function sortByKey()
    {
        $content = '';
        ksort($this->set); // substr($line,0,3) 排序

        foreach($this->set as $key => $val)
        {
            $val = array_keys($val);
            
            usort($val,"self::my_sort");  // substr($b,3,4) 排序
            
            unset($this->set[$key]);

            while($row = array_shift($val))
            {
                $content? $content.="\n$row":$content.=$row;
            }
        }
        $file = sha1($content);
        file_put_contents($file ,$content);
    }
    
    public static function my_sort($a,$b)
    {
        $front = substr($a,3,4);
        $back = substr($b,3,4);
        if ($front==$back) return 0;
        return ($front<$back)?-1:1;
    }

}

$start = time();
$clas = new data();
$clas->filter();
$clas->sortByKey();
$end = time();
echo 'time:',($end-$start),' second';    
$byte =  memory_get_peak_usage(false);
echo "\n Memcache max: ", $byte/1024/1024,' M';

 如果有更优的方法 请赐教

 posted on 2017-07-06 18:17  changs  阅读(364)  评论(0编辑  收藏  举报