2020年12月8日17:46:01
项目地址:https://gitee.com/zxadmin/phpCommonAlgorithms
<?php
namespace ZX\Algorithm;
/*
* 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 ZX\Algorithm\BitMap;
$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的长度