zoukankan      html  css  js  c++  java
  • PHP实现站点pv,uv统计(三)

    数据分析脚本如下:

    //error_reporting(0);
    date_default_timezone_set("PRC");
    $environment = get_cfg_var('app_flow_develop') ? get_cfg_var('app_flow_develop') : 3;
    define('BASEPATH',dirname(dirname(__FILE__)));
    switch($environment){
        case 1 :
            require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
            break;
        case 2 :
            require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
            break;
        default:
            require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.develop.php';
            break;
    }
    //删除其他的配置项
    unset($tjdomain);unset($config);unset($interval);unset($replace_a);
    require BASEPATH . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'logger.class.php';
    //0//cc : 是否支持写数据到浏览器(cookie,sessionStorage,localStorage,userData)
    //1//ck : 是否支持cookie
    //2//cl : 浏览器颜色位数
    //3//ds : 浏览器分辨率
    //4//fl : flash版本
    //5//ja : 是否支持java
    //6//ln : 浏览器语言
    //7//si : 统计id,站点标示
    //8//su : 来源url,只取了域名
    //9//kd : 关键词
    //10//tt : 站点title
    //11//cf : m点 1,站点0
    //12//uid : 会员id
    //13//pt : 平台
    //14//ocu : 操作系统
    //15//ua : 浏览器类型
    //16//tm : 请求时间
    //17//ip : 请求ip
    //18//u  : 站点url
    //19//uuid:唯一用户标识
    //20//basesu:原始su
    //21//baseu:原始u
    //22//basekd:原始关键词
    //23//u1:一级连接
    //24//u2:二级连接
    //25//u3:三级连接
    //26//u4:四级连接

    //获得时间节点
    $time = time();
    $Ymd = date("Ymd",$time);
    $H = date("G",$time);
    $i = floor(date("i",$time)/5);

    //处理昨天的最后一个五分钟区间
    if(0 == $i && 0 == $H){
        $Ymd = date("Ymd",strtotime('-1 days'));
        $H = 23;
        $i = 11;
    }
    //处理今天上一个小时的最后一个五分钟区间
    elseif(0 == $i && 0 != $H){
        $H--;
        $i = 11;
    }
    //处理上一个五分钟区间
    else{
        $i--;
    }

    //手动控制脚本的执行目录
    if(isset($_SERVER['argv'][1]) && $_SERVER['argv'][1]){
        if(isset($_SERVER['argv'][2]) && isset($_SERVER['argv'][3]) &&
            $_SERVER['argv'][2] >=0 &&
            $_SERVER['argv'][2] < 24 &&
            $_SERVER['argv'][3] >=0 &&
            $_SERVER['argv'][3] <12)
        {
            $Ymd = strval($_SERVER['argv'][1]);
            $H = strval($_SERVER['argv'][2]);
            $i = strval($_SERVER['argv'][3]);
            $handd0 = true;
        }else{
            echo 'parma error';
        }
    }

    //设置redis的key与操作目录地址
    $LOG_PATH = $LOG_BASE . DIRECTORY_SEPARATOR . $Ymd . DIRECTORY_SEPARATOR . $H . DIRECTORY_SEPARATOR . $i;
    $HOUR_PATH = dirname($LOG_PATH);
    $REDIS_DAY_KEY = $Ymd;
    $REDIS_HOUR_KEY = "{$Ymd}:{$H}";

    $log_base = new Logger($LOG_BASE . DIRECTORY_SEPARATOR  . 'error.log');

    //小时路径下的记录句柄,先检查有没有小时目录,没有的话报错
    if(file_exists($HOUR_PATH)){
        $log_hour = new Logger($HOUR_PATH . DIRECTORY_SEPARATOR  . 'error.log');
    }else{
        if(isset($handd0) && true === $handd0){
            echo $HOUR_PATH . ' is not exists please check the dir and retry';
            $log_base -> error($HOUR_PATH . ' is not exists by hand');
        }else{
            $log_base -> error($HOUR_PATH . ' is not exists ');
        }
        exit;
    }
    //如果有日志
    //这里的代码可以封装成一个类,当做一种对最小单元的一个处理方法,或者可以换成其他语言的脚本的调用,也方便单独手动处理数据
    //优化可以使用popen,proc_open,pcntl等方法多进程来处理
    if(file_exists($LOG_PATH)){
        //分钟路径下的记录句柄
        $log_do = new Logger($LOG_PATH . DIRECTORY_SEPARATOR  . 'do.txt');
        //切换目录,不然window下报错
        chdir($LOG_PATH);
        //判断是否完成这个区间
        if(!file_exists($LOG_PATH . '/done.txt')){
            //生成合并文件
            if(!file_exists($LOG_PATH . '/all.log')){
                $log_do -> notice(" combine files starts ");
                if(PHP_OS == 'WINNT'){
                    system("copy *.log all.log");
                } else {
                    system("cat *.log >> all.log");
                }
                //再次判断
                if(!file_exists($LOG_PATH . '/all.log')){
                    $log_hour -> error(" No.{$i} all log combine error");
                    exit;
                }
                $log_do -> notice(" combine files ends ");
            }
            //读取文件写redis缓存
            $log_do -> notice(" read all_log starts ");
            
            if($fp  =  fopen ($LOG_PATH . '/all.log',  "r")){
                if(flock($fp , LOCK_SH )) {
                    //初始化
                    $redis = new Redis();
                    $re = $redis->pconnect($REDIS_IP,$REDIS_PORT);
                    if(!$re){
                        $REDIS_FLAG = FALSE;
                    }else{
                        $REDIS_FLAG = TRUE;
                        //全站新的ip,uv,uid
                        $uv_new = $uid_new = $ip_new = array();
                        //u的新uv,su的新uv,kw的新uv
                        $u_uv = $su_uv = $kw_uv = array();

                    }
                    $ii=1;
                    //记录这段时间的pv
                    $si_array = $uv_array = $uid_array = $ip_array = $u_array = $su_array = $kw_array = array();
                    
                    //读取文件,填充数组
                    while($str = fgets($fp)){
                        //移除回车符
                        $str = trim($str,PHP_EOL);
                        $a = explode('~^~',$str);
                        if(27 != count($a)){
                            $log_do -> notice(" No.{$ii} data is bad type ");
                            continue;
                        }
                        //填充数组
                        if($a[7]){
                            //处理si,根据si再次初始化数组
                            //记录每个站点这段时间的pv总数
                            /*
                            $si_array(
                                '站点一'=>10,
                                '站点二'=>'20'
                            );
                            */
                            if(isset($si_array[$a[7]])) {
                                $si_array[$a[7]] += 1;
                            } else {
                                $si_array[$a[7]] = 1;
                                $uv_new[$a[7]] = $uid_new[$a[7]] = $ip_new[$a[7]] = array();
                                $u_uv[$a[7]] = $su_uv[$a[7]] = $kw_uv[$a[7]] = array();
                                $uv_array[$a[7]] = $uid_array[$a[7]] = $ip_array[$a[7]] = $kw_array[$a[7]] = $su_array[$a[7]] = $u_array[$a[7]] = array();
                                $si_array[$a[7]] = 1;
                            }
                            

                            //处理uv
                            if($a[19]){
                                //记录uv,记录后得到每个站点,每个uuid这段时间的pv数量
                                /*
                                $uv_array = array(
                                    '站点一'=>array(
                                        'uuid1'=>10,
                                        'uuid2'=>20,
                                    )
                                )
                                */
                                isset($uv_array[$a[7]][$a[19]]) ? $uv_array[$a[7]][$a[19]] += 1 : $uv_array[$a[7]][$a[19]] = 1;
                                //记录每个站点,这段时间的新的uv数量
                                /*
                                $uv_new = array(
                                    '站点一'=>array(
                                        'uuid1','uuid2'
                                    )
                                )
                                */
                                if($REDIS_FLAG){
                                    //不在这个时间段记录的数据里
                                    if(!in_array($a[19],$uv_new[$a[7]])){
                                        $exist = $redis->HEXISTS("{$REDIS_DAY_KEY}:{$a[7]}:UV:HASH",$a[19]);
                                        //不在今天的历史数据里(即新的uuid)
                                        if(!$exist){
                                            $uv_new[$a[7]][]= $a[19];
                                        }
                                    }
                                }
                            }
                            
                            //处理uid
                            if($a[12]){
                                //记录uid,记录后得到每个站点,每个uid这段时间的pv数量
                                /*
                                $uid_array = array(
                                    '站点一'=>array(
                                        'uid1'=>10,
                                        'uid2'=>20,
                                    )
                                )
                                */
                                isset($uid_array[$a[7]][$a[12]]) ? $uid_array[$a[7]][$a[12]] += 1 : $uid_array[$a[7]][$a[12]] = 1;
                                //记录每个站点,这段时间的新的uid数量
                                /*
                                $uid_new = array(
                                    '站点一'=>array(
                                        'uid1','uid2'
                                    )
                                )
                                */
                                if($REDIS_FLAG){
                                    if(!in_array($a[12],$uid_new[$a[7]])){
                                        $exist = $redis->HEXISTS("{$REDIS_DAY_KEY}:{$a[7]}:UID:HASH",$a[12]);
                                        if(!$exist){
                                            $uid_new[$a[7]][]= $a[12];
                                        }
                                    }
                                }
                            }
                            
                            //处理ip
                            if($a[17]){
                                //记录ip,记录后得到每个站点,每个ip这段时间的pv数量
                                /*
                                $ip_array = array(
                                    '站点一'=>array(
                                        'ip1'=>10,
                                        'ip2'=>20,
                                    )
                                )
                                */
                                isset($ip_array[$a[7]][$a[17]]) ? $ip_array[$a[7]][$a[17]] += 1 : $ip_array[$a[7]][$a[17]] = 1;
                                //记录每个站点,这段时间的新的ip数量
                                /*
                                $ip_new = array(
                                    '站点一'=>array(
                                        'ip1','ip2'
                                    )
                                )
                                */
                                if($REDIS_FLAG){
                                    if(!in_array($a[17],$ip_new[$a[7]])){
                                        $exist = $redis->HEXISTS("{$REDIS_DAY_KEY}:{$a[7]}:IP:HASH",$a[17]);
                                        if(!$exist){
                                            $ip_new[$a[7]][]= $a[17];
                                        }
                                    }
                                }
                            }
                            
                            
                            //特殊处理的项
                            //处理u
                            if($a[18]){
                                //处理一级Url
                                reg_u_common_op(23);
                                //处理二级Url
                                reg_u_common_op(24);
                                //处理三级Url
                                reg_u_common_op(25);
                                //处理四级Url
                                reg_u_common_op(26);
                            }
                            
                            //处理kw
                            if($a[9]){
                                //记录kw,记录后得到每个站点,每个kw这段时间的pv数量
                                /*
                                $kw_array = array(
                                    '站点一'=>array(
                                        'kw1'=>10,
                                        'kw2'=>20,
                                    )
                                )
                                */
                                isset($kw_array[$a[7]][$a[9]]) ? $kw_array[$a[7]][$a[9]] += 1 : $kw_array[$a[7]][$a[9]] = 1;
                                //记录每个站点,这段时间kw的新的uv数量
                                /*
                                $kw_new = array(
                                    '站点一'=>array(
                                        'kw1'=>array(
                                            'uuid1','uuid2'
                                        )
                                    )
                                )
                                */
                                if($REDIS_FLAG){
                                    if(!isset($kw_uv[$a[7]][$a[9]]) || !in_array($a[19],$kw_uv[$a[7]][$a[9]])){
                                        $exist = $redis->HEXISTS("{$REDIS_DAY_KEY}:{$a[7]}:{$a[9]}:KW:UV:HASH",$a[19]);
                                        if(!$exist){
                                            $kw_uv[$a[7]][$a[9]][]= $a[19];
                                        }
                                    }
                                }
                            }
                            
                            
                            //处理su
                            if($a[8]){
                                //记录su,记录后得到每个站点,每个su这段时间的pv数量
                                /*
                                $su_array = array(
                                    '站点一'=>array(
                                        'su1'=>10,
                                        'su2'=>20,
                                    )
                                )
                                */
                                isset($su_array[$a[7]][$a[8]]) ? $su_array[$a[7]][$a[8]] += 1 : $su_array[$a[7]][$a[8]] = 1;
                                //记录每个站点,这段时间su的新的uv数量
                                /*
                                $kw_new = array(
                                    '站点一'=>array(
                                        'kw1'=>array(
                                            'uuid1','uuid2'
                                        )
                                    )
                                )
                                */
                                if($REDIS_FLAG){
                                    if(!isset($su_uv[$a[7]][$a[8]]) || !in_array($a[19],$su_uv[$a[7]][$a[8]])){
                                        $exist = $redis->HEXISTS("{$REDIS_DAY_KEY}:{$a[7]}:{$a[8]}:SU:UV:HASH",$a[19]);
                                        if(!$exist){
                                            $su_uv[$a[7]][$a[8]][]= $a[19];
                                        }
                                    }
                                }
                            }
                            

                        }else{
                            $log_do -> notice(" No.{$ii} data empty si ");
                            continue;
                        }

                        $ii++;
                        unset($a);
                    }
                    $log_do -> notice(" read all_log is complete ");
                    
                    //填充redis
                    //记录redis记录开始
                    if($REDIS_FLAG){
                        $log_do -> notice(" set redis start ");
                        //记录站点的pv总数
                        foreach($si_array as $k => $v){
                            $redis->HINCRBY("{$REDIS_DAY_KEY}:{$k}:QZ:HASH","PV",$v);
                            $redis->HINCRBY("{$REDIS_HOUR_KEY}:{$k}:QZ:HASH","PV",$v);
                        }
                        
                        //记录站点的uv总数
                        foreach($uv_new as $k => $v){
                            $uv_num = count($v);
                            $redis->HINCRBY("{$REDIS_DAY_KEY}:{$k}:QZ:HASH","UV",$uv_num);
                            $redis->HINCRBY("{$REDIS_HOUR_KEY}:{$k}:QZ:HASH","UV",$uv_num);
                            //插入当天的uv唯一hash
                            $flip_uv = array_flip($v);
                            $redis->HMSET("{$REDIS_DAY_KEY}:{$k}:UV:HASH",$flip_uv);
                        }
                        
                        //记录站点的uid总数
                        foreach($uid_new as $k => $v){
                            $uid_num = count($v);
                            $redis->HINCRBY("{$REDIS_DAY_KEY}:{$k}:QZ:HASH","UID",$uid_num);
                            $redis->HINCRBY("{$REDIS_HOUR_KEY}:{$k}:QZ:HASH","UID",$uid_num);
                            //插入当天的uv唯一hash
                            $flip_uid = array_flip($v);
                            $redis->HMSET("{$REDIS_DAY_KEY}:{$k}:UID:HASH",$flip_uid);
                        }
                        
                        //记录站点的ip总数
                        foreach($ip_new as $k => $v){
                            $ip_num = count($v);
                            $redis->HINCRBY("{$REDIS_DAY_KEY}:{$k}:QZ:HASH","IP",$ip_num);
                            $redis->HINCRBY("{$REDIS_HOUR_KEY}:{$k}:QZ:HASH","IP",$ip_num);
                            //插入当天的uv唯一hash
                            $flip_ip = array_flip($v);
                            $redis->HMSET("{$REDIS_DAY_KEY}:{$k}:IP:HASH",$flip_ip);
                        }
                        
                        //记录站点u的pv,uv
                        foreach($u_uv as $k => $v){
                            foreach($v as $kk => $vv){
                                $u_uv_num = count($vv);
                                $u_pv_num = $u_array[$k][$kk];
                                $redis->ZINCRBY("{$REDIS_DAY_KEY}:{$k}:U:PV:ZSET",$u_pv_num,$kk);
                                $redis->ZINCRBY("{$REDIS_HOUR_KEY}:{$k}:U:PV:ZSET",$u_pv_num,$kk);
                                
                                $redis->ZINCRBY("{$REDIS_DAY_KEY}:{$k}:U:UV:ZSET",$u_uv_num,$kk);
                                $redis->ZINCRBY("{$REDIS_HOUR_KEY}:{$k}:U:UV:ZSET",$u_uv_num,$kk);
                                //插入当天的uv唯一hash
                                $flip_u_uv = array_flip($vv);
                                $redis->HMSET("{$REDIS_DAY_KEY}:{$k}:{$kk}:U:UV:HASH",$flip_u_uv);
                            }
                        }
                        
                        //记录站点kw的pv,uv
                        foreach($kw_uv as $k => $v){
                            foreach($v as $kk => $vv){
                                $kw_uv_num = count($vv);
                                $kw_pv_num = $kw_array[$k][$kk];
                                $redis->ZINCRBY("{$REDIS_DAY_KEY}:{$k}:KW:PV:ZSET",$kw_pv_num,$kk);
                                $redis->ZINCRBY("{$REDIS_HOUR_KEY}:{$k}:KW:PV:ZSET",$kw_pv_num,$kk);
                                
                                $redis->ZINCRBY("{$REDIS_DAY_KEY}:{$k}:KW:UV:ZSET",$kw_uv_num,$kk);
                                $redis->ZINCRBY("{$REDIS_HOUR_KEY}:{$k}:KW:UV:ZSET",$kw_uv_num,$kk);
                                //插入当天的uv唯一hash
                                $flip_kw_uv = array_flip($vv);
                                $redis->HMSET("{$REDIS_DAY_KEY}:{$k}:{$kk}:KW:UV:HASH",$flip_kw_uv);
                            }
                        }
                        
                        //记录站点su的pv,uv
                        foreach($su_uv as $k => $v){
                            foreach($v as $kk => $vv){
                                $su_uv_num = count($vv);
                                $su_pv_num = $su_array[$k][$kk];
                                $redis->ZINCRBY("{$REDIS_DAY_KEY}:{$k}:SU:PV:ZSET",$su_pv_num,$kk);
                                $redis->ZINCRBY("{$REDIS_HOUR_KEY}:{$k}:SU:PV:ZSET",$su_pv_num,$kk);
                                
                                $redis->ZINCRBY("{$REDIS_DAY_KEY}:{$k}:SU:UV:ZSET",$su_uv_num,$kk);
                                $redis->ZINCRBY("{$REDIS_HOUR_KEY}:{$k}:SU:UV:ZSET",$su_uv_num,$kk);
                                //插入当天的uv唯一hash
                                $flip_su_uv = array_flip($vv);
                                $redis->HMSET("{$REDIS_DAY_KEY}:{$k}:{$kk}:SU:UV:HASH",$flip_su_uv);
                            }
                        }
                        $log_do -> notice(" set redis is complete ");
                    }
                    //记录redis记录结束
                    
                    
                    //记录统计数据
                    //记录统计记录开始
                    $log_do -> notice(" write analyse data starts ");
                    if($REDIS_FLAG){
                        file_put_contents($LOG_PATH . '/uv_new.log', var_export(json_encode($uv_new),true), FILE_APPEND);
                        
                        file_put_contents($LOG_PATH . '/uid_new.log', var_export(json_encode($uid_new),true), FILE_APPEND);
                        
                        file_put_contents($LOG_PATH . '/ip_new.log', var_export(json_encode($ip_new),true), FILE_APPEND);
                        
                        file_put_contents($LOG_PATH . '/u_uv.log', var_export(json_encode($u_uv),true), FILE_APPEND);
                        
                        file_put_contents($LOG_PATH . '/su_uv.log', var_export(json_encode($su_uv),true), FILE_APPEND);
                        
                        file_put_contents($LOG_PATH . '/kw_uv.log', var_export(json_encode($kw_uv),true), FILE_APPEND);
                    }
                    
                    file_put_contents($LOG_PATH . '/uv_array.log', var_export(json_encode($uv_array),true), FILE_APPEND);
                    
                    file_put_contents($LOG_PATH . '/uid_array.log', var_export(json_encode($uid_array),true), FILE_APPEND);
                    
                    file_put_contents($LOG_PATH . '/ip_array.log', var_export(json_encode($ip_array),true), FILE_APPEND);
                    
                    file_put_contents($LOG_PATH . '/kw_array.log', var_export(json_encode($kw_array),true), FILE_APPEND);
                    
                    file_put_contents($LOG_PATH . '/su_array.log', var_export(json_encode($su_array),true), FILE_APPEND);
                    
                    file_put_contents($LOG_PATH . '/u_array.log', var_export(json_encode($u_array),true), FILE_APPEND);
                    
                    file_put_contents($LOG_PATH . '/si_array.log', var_export(json_encode($si_array),true), FILE_APPEND);
                    //记录统计记录完毕
                    $log_do -> notice(" write analyse data is complete ");
                    
                    //释放变量
                    if($REDIS_FLAG){
                        unset($ip_new);
                        unset($uv_new);
                        unset($uid_new);
                        unset($u_uv);
                        unset($su_uv);
                        unset($kw_uv);
                    }
                    unset($uv_array);
                    unset($uid_array);
                    unset($ip_array);
                    unset($kw_array);
                    unset($su_array);
                    unset($u_array);
                    
                    $log_do -> notice(" release var is complete ");
                    flock ( $fp , LOCK_UN);
                } else {
                    $log_do -> notice(" all.log flock failed ");
                }
                fclose ( $fp );
            }else{
                $log_hour -> error(" No.{$i} all.log fopen error ");
                exit;
            }
            //记录完成
            $now = date("Y-m-d H:i:s");
            $log_do -> notice(" No.{$i} job done at {$now} ");
            file_put_contents($LOG_PATH . DIRECTORY_SEPARATOR . 'done.txt', $now . " No.{$i} job is done" . PHP_EOL, FILE_APPEND);
            $log_hour -> notice(" No.{$i} job done at {$now} ");
            if(isset($handd0) && true === $handd0){
                echo " No.{$i} job done at {$now} ";
            }
        }else{
            $log_hour -> notice(" No.{$i} alread done ");
        }
    }else{
        $log_hour -> error(" No.{$i} dir not exist ");
    }

    //处理各级url的通用方法
    function reg_u_common_op($u_no){
        //引入全局变量
        global $a,$u_array,$REDIS_DAY_KEY,$redis,$REDIS_FLAG,$u_uv;
        if($a[$u_no]){
            //记录u,记录后得到每个站点,每个url这段时间的pv数量
            /*
            $u_array = array(
                '站点一'=>array(
                    'u1'=>10,
                    'u2'=>20,
                )
            )
            */
            isset($u_array[$a[7]][$a[$u_no]]) ? $u_array[$a[7]][$a[$u_no]] += 1 : $u_array[$a[7]][$a[$u_no]] = 1;
            //记录每个站点,这段时间的u新的uv数量
            /*
            $u_uv = array(
                '站点一'=>array(
                    'URL一'=>array(
                        'uuid1','uuid2'
                    )
                )
            )
            */
            if($REDIS_FLAG){
                if(!isset($u_uv[$a[7]][$a[$u_no]]) || !in_array($a[19],$u_uv[$a[7]][$a[$u_no]])){
                    $exist = $redis->HEXISTS("{$REDIS_DAY_KEY}:{$a[7]}:{$a[$u_no]}:U:UV:HASH",$a[19]);
                    if(!$exist){
                        $u_uv[$a[7]][$a[$u_no]][]= $a[19];
                    }
                }
            }
        }
    }
    exit;

    附上nginx的server配置:

    server {
        listen 80;
        server_name 18touch.tongji.com;
        index index.php index.html index.htm;
        root /home/tongji/webroot;
        
        rewrite ^/h.js$ /js.php last;
        rewrite ^/m.gif$ /hm.php last;
        
        include global/restrictions.conf;
        
        location ~ .php$ { 
            fastcgi_pass  php78;
            fastcgi_index index.php; 
            fastcgi_param SCRIPT_FILENAME /home/tongji/webroot$fastcgi_script_name; 
            include fastcgi_params; 
        }
        
        location ~ /888/$ { 
            empty_gif;
            fastcgi_pass  php78;
            fastcgi_index index.php; 
            fastcgi_param SCRIPT_FILENAME /home/tongji/webroot/hm.php; 
            include fastcgi_params;
        }
    }

    剩下从redis每日获取昨天的统计数据,然后存储到文本或者mysql。

    PS:对目录的操作在win与linux下的函数效果不同,注意文件夹的权限,写文本也有不同。

    统计数据从文本返回到php的脚本:

    $fp  =  fopen ('uv_array.log',  "r");
    while($str = fgets($fp)){
        $str = "$str = " . trim($str,PHP_EOL) .";";
        eval($str);
        $a = json_decode($str,true);
        var_dump($a);exit;
    }
  • 相关阅读:
    1041. 困于环中的机器人
    95. 不同的二叉搜索树 II
    LeetCode945:使数组唯一的最小增量
    LeetCode:925.长按键入
    LeetCode:926. 将字符串翻转到单调递增
    InteliJ 安装PlantUML插件
    CodeBlock换肤
    正则表达式验证手机号和座机号
    C#中使用反射遍历一个对象属性和值以及百分数
    c#中@的用法
  • 原文地址:https://www.cnblogs.com/kudosharry/p/3904732.html
Copyright © 2011-2022 走看看