经过多方面的资料收集,我们来看看 php实现位图法 是怎么做的。
1、我们知道 1G=1024M 1M=1024KB 1KB=1024byte 1byte=8bit 也就是一个字节等于8bit 也就是8个二进制位,位图法的概念是用一个位来标记某个数的存放状态,所以节省了大量的空间。
2、数据结构
unsigned int bit[N] 这个数组里面,可以储存 N * PHP_INT_SIZE *8 个数据,但最大的数是 N * PHP_INT_SIZE *8-1。 例如我们要存储的数据范围为0-63,则我们只需要将 N=1 ,这样就可以把数据存进去。
例外: 操作系统分32位 和 64位 32位 PHP_INT_SIZE =4 64位 PHP_INT_SIZE =8
code1.png
如果是32位系统 ,则 N=2
如果是64位系统 ,则 N=1
数据为[5,1,7,15,0,4,6,10,14],将这些数据存入这个结构中为
bitMap 方法 把数组位图化,并以数组的形式返回:
function bitmap($data, $int = 10) {
$bitmap = array_fill(0, $int, 0);
$int_bit_size = PHP_INT_SIZE * 8;
foreach ($data as $item) {
//字节位置
$bytePos = $item / $int_bit_size;
$bitPos = $item % $int_bit_size;
$position = 1 << $bitPos;
isset($bitmap[$bytePos]) || $bitmap[$bytePos] = 0;
// printf("item:%d position:%d 格子:%d 表达式:%d|%d=%d\n", $item, $position, $bytePos, $bitmap[$bytePos], $position, $bitmap[$bytePos] | $position);
$bitmap[$bytePos] = $bitmap[$bytePos] | $position;
}
return $bitmap;
}调用方法:$arr = [5, 1, 7, 15, 0, 4, 6, 10, 14, 88];
$bitmap = bitmap($arr);===================简单对bitmap做个介绍===========================$arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31];
$bit_int_size=PHP_INT_SIZE*8; 这个结果是32 按理说,可以存储32个数据,
PHP_INT_MAX php最大值是 2147483647
当储存大于这个数字的时候,位移 会现出 -1 的情况
为了避免这个问题, 我们把bit_int_size=PHP_INT_SIZE*8-1 少保存一个,这样最大保存 2147483647 就不会出现负数。
这里的一个改动,其他地方也要 跟着进行修改。
===================简单对bitmap做个介绍===========================
使用方法:
checkExists($bitmap, 999145);
备注:
存储的数组中,数据不能重复,会替换。
例如说:
$arr = [5, 1, 7, 15, 0, 4, 6, 10, 14, 88, 15];
数组中有两个 15 ,只会保留一个 15,
且 getdata($bitmap)后,数据会从小到大依次排序
Array
(
[0] => 0
[1] => 1
[2] => 4
[3] => 5
[4] => 6
[5] => 7
[6] => 10
[7] => 14
[8] => 15
[9] => 88
)
只保留了一个15 ,且 顺序是从小到的 依次排序的。
这里还有一个功能就是可以做排序噢!
下面进行封装了一个类:
Bitmap.php
class Bitmap {
public static $_instance = NULL;
public $int_bit_size = NULL;
private $_bitmap = [];
public function __construct() {
$this->int_bit_size = PHP_INT_SIZE * 8 - 1;
}
.....
//调用方法:
public function testAction() {
$arr = [5, 1, 7, 15, 0, 4, 6, 10, 14, 88];
//$arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 99, 9, 10, 11, 12, 90, 13, 14, 15, 16, 17, 100, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 40, 50, 60];
$bitMap = new Bitmap();
$bitdata = $bitMap->createBitMap($arr)->getBitmap();
$ishave = $bitMap->checkExists(88);
printf('数组中%s是否含有88 ::::: %s<br>', var_export($arr, TRUE), is_null($ishave) ? '无' : '有');
P($bitdata);
printf('数组中%s是否含有77 ::::: %s<br>', var_export($arr, TRUE), is_null($bitMap->checkExists(77)) ? '无' : '有');
$bitMap->addData(77);
printf('添加一个77<br>');
printf('数组中%s是否含有77 ::::: %s<br>', var_export($arr, TRUE), is_null($bitMap->checkExists(77)) ? '无' : '有');
printf('删除88<br>');
$bitMap->delData(88);
printf('数组中%s是否含有88 ::::: %s<br>', var_export($arr, TRUE), is_null($bitMap->checkExists(88)) ? '无' : '有');
printf('获取原始数组<br>');
P($bitMap->getData());
//排序功能
//$sortData = Bitmap::bitSort($arr);
//P($sortData);
}
php按位运算轻松管理百万级数据 http://shorturl.xiaosongit.com/vUKjp2
百万级数据查找保存问题结合位图法详细说明 http://shorturl.xiaosongit.com/Y9q8y1
php实现位图法,处理海量数据 http://shorturl.xiaosongit.com/llLaw2
最佳答案