• PHP实现bitmap算法


    2020年12月8日17:46:01

    项目地址:https://gitee.com/zxadmin/phpCommonAlgorithms

    <?php
    
    namespace ZXAlgorithm;
    
    /*
     * bitmap算法
     */
    
    final class BitMap {
    
        //int 位数
        private static $phpIntSize = PHP_INT_SIZE;
        //int最大值  Usually int(2147483647) in 32 bit systems and int(9223372036854775807) in 64 bit systems. Available since PHP 5.0.5
        private static $phpIntMax = PHP_INT_MAX;
        //最大位数64位 1 << 6 32位 1 << 5
        private static $max = (1 << 6 ) - 1;
        //储存数据的变量
        private static $data = [];
    
        public static function addValue(int $n) {
            //
            $row = $n >> 6;
            //余数
            $index = $n % self::$max;
            //或运算保证占位不被覆盖
            self::$data[$row] |= 1 << $index;
        }
    
        // 判断所在的bit为是否为1
        public static function exits(int $n) {
            $row = $n >> 6;
            $index = $n % self::$max;
    
            $result = self::$data[$row] & (1 << $index);
    //        p($result);
            return $result != 0;
        }
    
        public static function getData() {
            return self::$data;
        }
    
    }

    原理比较简单,吧数组元素降低维度到二进制数位上,利用商做key,余数作为位数,通过位运算来做数据统计

    测试

    
    
    <?php
    
    include_once './../src/Algorithm/BitMap.php';
    include_once './../src/Algorithm/BitOperation.php';
    
    include_once './Function.php';
    
    use ZXAlgorithmBitMap;
    
    $arr = [0, 1, 3, 16, 42, 69, 18, 11, 99, 32421, 32423, 32525, 9999999999];
    foreach ($arr as $v) {
        BitMap::addValue($v);
    }
    //$tt = BitMap::getData();
    $rr = BitMap::exits(16);
    
    if ($rr) {
        p('ok');
    } else {
        p('no');
    }
    
    ////海量数据测试,php8 的jit效果更好
    //ini_set('memory_limit', '4096M');
    ////2000两千万数据
    //for ($index = 0; $index < 100000000; $index = $index + 5) {
    //    BitMap::addValue($index);
    //}
    //$rr = BitMap::exits(25);
    //if ($rr) {
    //    p('ok');
    //} else {
    //    p('no');
    //}
    
    
    
     

    几个小技巧总结:

    任何判断二进制那个位置是1

    N:待判断的二进制数
    B:待判断的位(右往左)
    $n = 11;
    p(base_convert($n, 10, 2));
    $b = 2;
    $rr = $n >> ($b - 1) & 1;
    p($rr);
    结果:((N>>(B-1))&1

    注意:$max = (1 << 6 ) - 1; 和 $max = 1 << 6  - 1;

    不是一个意思

    9223372036854775807是64位最大的证书是63的长度

  • 相关阅读:
    深度排序与alpha混合 【转】
    SVN服务器配置说明 【转】
    3D空间中射线与轴向包围盒AABB的交叉检测算法 【转】
    Linux系统管理员不可不知的命令:sudo
    Linux 系统实时监控的瑞士军刀 —— Glances
    shell定期转移日志文件到云盘并定期删除云盘文件
    zabbix监控第二块网卡是否连通
    Gitlab自动触发Jenkins构建打包
    shell脚本检测网络是否畅通
    Prometheus入门
  • 原文地址:https://www.cnblogs.com/zx-admin/p/14104323.html
Copyright © 2020-2023  润新知