2014年12月16日 17:15:09

初始化一串全为0的二进制;

现有一串无序的整数数组;

如果整数x在这个整数数组当中,就将二进制串的第x位置为1;

然后顺序读取这个二进制串,并将为1的位转换成整数,顺序存放到新的集合中,就是排好序的了

排序代码:

  1. function sort()
  2. {
  3. // var_dump(PHP_INT_MAX, PHP_INT_SIZE);
  4. // int 9223372036854775807
  5. // int 8
  6. $bitmap = array_fill(0, 50, 0); //申请一个整形数组, 50个元素, 初始化为整数0
  7. $int_bit_size = PHP_INT_SIZE * 8; //$bitmap中每个整形的二进制位数 (本例中int = 8*8 = 64bit; $bitmap数组一共50*64 = 3200个bit位),也就是说能为最大值小于等于3200的整数集合排序
  8. $a = array(1,4,3,50,34,60,100,88,200,150,300); //定义一个乱序的数组
  9.  
  10. //扫描$a中的每一个数, 将其转换为 x*64 + y
  11. foreach ($a as $k => $v) {
  12. $shang = $v / $int_bit_size;
  13. $yushu = $v % $int_bit_size;
  14.  
  15. $offset = 1 << $yushu;
  16.  
  17. $bitmap[$shang] = $bitmap[$shang] | $offset;//将bit位置为1
  18. }
  19.  
  20. //将$bitmap中的bit位依次还原为整数输出,即可得到排序后的数组
  21. $b = array();
  22. foreach ($bitmap as $k => $v) {
  23. for ($i = 0; $i < $int_bit_size; $i++) {
  24. $tmp = 1 << $i;
  25. $flag = $tmp & $bitmap[$k];
  26.  
  27. // $b[] = $flag ? $k * $int_bit_size + $i : false;
  28. if ($flag) {
  29. $b[] = $k * $int_bit_size + $i;
  30. }
  31. }
  32. }
  33.  
  34. var_dump($b);exit;
  35. }
  36. // 浏览器输出:
  37. array
  38. 0 => int 1
  39. 1 => int 3
  40. 2 => int 4
  41. 3 => int 34
  42. 4 => int 50
  43. 5 => int 60
  44. 6 => int 88
  45. 7 => int 100
  46. 8 => int 150
  47. 9 => int 200
  48. 10 => int 300

求交集代码:

生成两个bitmap -> 循环两个bitmap 与操作 生成一个新的bitmap -> 还原bitmap为数字

  1. public function sort($a = array())
  2. {
  3. // var_dump(PHP_INT_MAX, PHP_INT_SIZE);
  4. // int 9223372036854775807
  5. // int 8
  6. $bitmap = array_fill(0, 50, 0); //申请一个整形数组, 50个元素, 初始化为整数0
  7. $int_bit_size = PHP_INT_SIZE * 8; //$bitmap中每个整形的二进制位数 (本例中int = 8*8 = 64bit; $bitmap数组一共50*64 = 3200个bit位)
  8. // $a = array(1,4,3,50,34,60,100,88,200,150,300); //定一个乱序的数组
  9.  
  10. //扫描$a中的每一个数, 将其转换为 x*64 + y
  11. foreach ($a as $k => $v) {
  12. $shang = $v / $int_bit_size;
  13. $yushu = $v % $int_bit_size;
  14.  
  15. $offset = 1 << $yushu;
  16.  
  17. $bitmap[$shang] = $bitmap[$shang] | $offset;//将bit位置为1
  18. }
  19.  
  20. return $bitmap;
  21. }
  22.  
  23. public function intersect()
  24. {
  25. $int_bit_size = PHP_INT_SIZE * 8;
  26.  
  27. $a = array(1,4,3,50,34,60,100,88,200,150,300);
  28. $b = array(1,5,3,50,34,55,100,87,222,150,300);
  29.  
  30. $bit_a = $this->sort($a);
  31. $bit_b = $this->sort($b);
  32.  
  33. $c = array();
  34. foreach ($bit_a as $k => $v) {
  35. $c[$k] = $bit_a[$k] & $bit_b[$k]; //二进制 & 计算求交集
  36. }
  37.  
  38. $d = array();
  39. foreach ($c as $k => $v) {
  40. for ($i = 0; $i < $int_bit_size; $i++) {
  41. $tmp = 1 << $i;
  42. $flag = $tmp & $c[$k];
  43.  
  44. // $b[] = $flag ? $k * $int_bit_size + $i : false;
  45. if ($flag) {
  46. $d[] = $k * $int_bit_size + $i;
  47. }
  48. }
  49. }
  50.  
  51. var_dump($d);exit;
  52.  
  53. }
  54. 浏览器输出:
  55. array
  56. 0 => int 1
  57. 1 => int 3
  58. 2 => int 34
  59. 3 => int 50
  60. 4 => int 100
  61. 5 => int 150
  62. 6 => int 300

参考:

http://kevinbest0702.blog.163.com/blog/static/85409746201291484128939/

http://www.cnblogs.com/dolphin0520/archive/2011/10/19/2217369.html

PHP实现 bitmap 位图排序 求交集的更多相关文章

  1. list1与list2求交集的方法总结!

    一.有序集合求交集的方法有 a)二重for循环法,时间复杂度O(n*n) b)拉链法,时间复杂度O(n) c)水平分桶,多线程并行 d)bitmap,大大提高运算并行度,时间复杂度O(n) e)跳表, ...

  2. Bitmap 位图

    转自: http://dongxicheng.org/structure/bitmap/ 1.  概述 位图(bitmap)是一种非常常用的结构,在索引,数据压缩等方面有广泛应用.本文介绍了位图的实现 ...

  3. javascript集合求交集

    两集合求交集 思路: 1. 每一次从B数组中取一值,然后在A数组里逐个比较,如果有相等的,则保存.该算法复杂度为 O(MN). M, N 分别为数组 A B 的长度. 2. 因为A B 都排过序,所以 ...

  4. Linux 两个文件求交集、并集、差集

    一.交集 sort a.txt b.txt | uniq -d 二.并集 sort a.txt b.txt | uniq 三.差集 a.txt-b.txt: sort a.txt b.txt b.tx ...

  5. ( 转 ) 数据库BTree索引、Hash索引、Bitmap位图索引的优缺点

    测试于:MySQL 5.5.25 当前测试的版本是Mysql 5.5.25只有BTree和Hash两种索引类型,默认为BTree.Oracle或其他类型数据库中会有Bitmap索引(位图索引),这里作 ...

  6. wukong引擎源码分析之搜索——docid有序的数组里二分归并求交集,如果用跳表的话,在插入索引时会更快

    searcher.Search(types.SearchRequest{Text: "百度中国"}) // 查找满足搜索条件的文档,此函数线程安全 func (engine *En ...

  7. ACM_求交集

    求交集 Time Limit: 2000/1000ms (Java/Others) Problem Description: 输入集合A和B,按大小顺序输出A和B的交集. Input: 输入包含多组测 ...

  8. BitMap位图

    BitMap位图算法https://blog.csdn.net/varyall/article/details/79662029 常见面试题 题1:在2.5亿个整数找出不重复的整数,内存不足以容纳着2 ...

  9. POJ 2388 Who's in the Middle(水~奇数个数排序求中位数)

    题目链接:http://poj.org/problem?id=2388 题目大意: 奇数个数排序求中位数 解题思路:看代码吧! AC Code: #include<stdio.h> #in ...

随机推荐

  1. Ajax、反向Ajax和WebSocket 概念

    Ajax 异步的JavaScript和XML(Asynchronous JavaScript and XML,Ajax),一种可通过JavaScript来访问的浏览器功能特性,其允许脚本向幕后的网站发 ...

  2. Java设计模式-抽象工厂模式(Abstract Factory )

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这 ...

  3. Query对象与DOM对象之间的转换方法

    转自http://www.jquerycn.cn/a_4561 刚开始学习jQuery,可能一时会分不清楚哪些是jQuery对象,哪些是DOM对象.至于DOM对象不多解释,我们接触的太多了,下面重点介 ...

  4. sprintf、strcpy和memcpy的区别

    做某题用到了sprintf把一个字符数组(字符串)写到二维字符数组里,然后耗时挺长的,想了想strcpy好像也可以,事实证明strcpy效率果然更高,然后想了想觉得memcpy好像也可以.实践了一下的 ...

  5. 【心得&&体会】

    ★2016.1.1★ 很早就想写这样的一篇blog了,但一直没有抽空去实现,新的一年感觉应该有所改变,故深夜提笔(码字) NOIP卡掉和连续两次月考爆炸,这段时间确实心理不舒服,调节的也不是很到位,但 ...

  6. 【bzoj1562】 NOI2009—变换序列

    http://www.lydsy.com/JudgeOnline/problem.php?id=1562 (题目链接) 题意 给出一个序列(0~n-1),这个序列经过某个变换会成为另外一个序列,但是其 ...

  7. 如果您想省略JS里的分号,了解一下JS的分号插入原理吧

    仅在}之前.一个或多个换行之后和程序输入的结尾被插入 也就是说你只能在一行.一个代码块和一段程序结束的地方省略分号. 也就是说你可以写如下代码 function square(x) { var n = ...

  8. 巧用section在cshtml写入layout中写入head信息 ASP.NET MVC

    转自:http://www.cnblogs.com/a-xu/archive/2012/05/08/2489746.html layout文件中: <head> <meta char ...

  9. 一段代码了解Java中char和int的转换

    题目要求: 将输入的大写字母转成对应小写的后5个,如A转换后为f:如果转换后大于z则从a重新计,即多出1就转成a,多出2就转成b以此类推. Java代码: ```java private static ...

  10. JS 瀑布流布局

    瀑布流布局 HTML <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...