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的长度