PHP实现 bitmap 位图排序 求交集

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

求交集代码:

public function sort($a = array())
    {
        // var_dump(PHP_INT_MAX, PHP_INT_SIZE);
        // int 9223372036854775807
        // int 8
        $bitmap = array_fill(0, 50, 0); //申请一个整形数组, 50个元素, 初始化为整数0
        $int_bit_size = PHP_INT_SIZE * 8; //$bitmap中每个整形的二进制位数 (本例中int = 8*8 = 64bit; $bitmap数组一共50*64 = 3200个bit位)
        // $a = array(1,4,3,50,34,60,100,88,200,150,300); //定一个乱序的数组

        //扫描$a中的每一个数, 将其转换为 x*64 + y
        foreach ($a as $k => $v) {
            $shang = $v / $int_bit_size;
            $yushu = $v % $int_bit_size;

            $offset = 1 << $yushu;

            $bitmap[$shang] = $bitmap[$shang] | $offset;//将bit位置为1
        }

        return $bitmap;
    }

    public function intersect()
    {
        $int_bit_size = PHP_INT_SIZE * 8;

        $a = array(1,4,3,50,34,60,100,88,200,150,300);
        $b = array(1,5,3,50,34,55,100,87,222,150,300);

        $bit_a = $this->sort($a);
        $bit_b = $this->sort($b);

        $c = array();
        foreach ($bit_a as $k => $v) {
            $c[$k] = $bit_a[$k] & $bit_b[$k]; //二进制 & 计算求交集
        }

        $d = array();
        foreach ($c as $k => $v) {
            for ($i = 0; $i < $int_bit_size; $i++) {
                $tmp = 1 << $i;
                $flag = $tmp & $c[$k];

                // $b[] = $flag ? $k * $int_bit_size + $i : false;
                if ($flag) {
                    $d[] =  $k * $int_bit_size + $i;
                }
            }
        }

        var_dump($d);exit;

    }
浏览器输出:
array
  0 => int 1
  1 => int 3
  2 => int 34
  3 => int 50
  4 => int 100
  5 => int 150
  6 => int 300

参考:

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

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

时间: 2024-11-03 22:11:01

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

[原]关于对求两个排序数组交集的扫描算法正确性的证明

在看<信息检索导论>的时候看到了这个算法的实现,书里是用来演示如何将两个term的倒排列表求交集.伪代码如下: INTERSECT( p1, p2 ) 1 answer ← {} 2 while p1 != NIL and p2 != NIL do 3   if docID( p1) = docID( p2 ) then 4     ADD( answer, docI D( p1 ) ) 5     p1 ← next( p1 ) 6     p2 ← next( p2 ) 7   else

Bitmap 位图

1.  概述 位图(bitmap)是一种非常常用的结构,在索引,数据压缩等方面有广泛应用.本文介绍了位图的实现方法及其应用场景. 2. 位图实现 (1)自己实现 在位图中,每个元素为"0"或"1",表示其对应的元素不存在或者存在. #define INT_BITS sizeof(int) #define SHIFT 5 // 2^5=32 #define MASK 0x1f // 2^5=32 #define MAX 1024*1024*1024 //max num

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

一.有序集合求交集的方法有 a)二重for循环法,时间复杂度O(n*n) b)拉链法,时间复杂度O(n) c)水平分桶,多线程并行 d)bitmap,大大提高运算并行度,时间复杂度O(n) e)跳表,时间复杂度为O(log(n)) 以下是方法的具体介绍: 方案一:for * for,土办法,时间复杂度O(n*n) 每个搜索词命中的网页是很多的,O(n*n)的复杂度是明显不能接受的.倒排索引是在创建之初可以进行排序预处理,问题转化成两个有序的list求交集,就方便多了. 方案二:有序list求交集

Java大集合求交集的方法比较

两个List集合求交集想必学过Java的都知道用系统自带的retainAll()方法,但是在数据量比较大时,这个方法效率并不高,利用空余时间研究了几种数据量较大时求两个集合交集的办法.本文主要研究了JDK自带方法求交集.Guava集合求交集.Java8的parallelStream并行流求交集.双指针方法求交集以及bitmap求交集的方法和效率. JDK自带方法 最常用的求交集方法,在小数据量的时候没什么问题,一旦两个集合的数据量达到几十万级别时,效率就严重偏低,底层实际上也是两个for循环,只

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

一.交集 sort a.txt b.txt | uniq -d 二.并集 sort a.txt b.txt | uniq 三.差集 a.txt-b.txt: sort a.txt b.txt b.txt | uniq -u b.txt - a.txt: sort b.txt a.txt a.txt | uniq -u 四.相关的解释 使用sort可以将文件进行排序,可以使用sort后面的玲玲,例如 -n 按照数字格式排序,例如 -i 忽略大小写,例如使用-r 为逆序输出等 uniq为删除文件中重

ecnu1624求交集多边形面积

链接 本来在刷hdu的一道题..一直没过,看到谈论区发现有凹的,我这种方法只能过凸多边形的相交面积.. 就找来这道题试下水. 两个凸多边形相交的部分要么没有 要么也是凸多边形,那就可以把这部分单独拿出来极角排序.叉积求面积.这部分的顶点要么p在q内的顶点,要么是q在p内的顶点,要么是两凸多边形的交点. 用到了点在多边形内的判定模板. 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #inclu

计数排序与位图排序

计数排序(Counting sort)是一种稳定的线性时间排序算法.计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数.然后根据数组C来将A中的元素排到正确的位置.计数排序不是比较排序,排序的速度快于任何比较排序算法.由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存.计数排序更适合于小范围集合的排序.比如100万学生参加高考,我们想对这100万学生的数学成绩(

牛客网NowCoder 2018年全国多校算法寒假训练营练习比赛(第四场)A.石油采集(dfs) B.道路建设(最小生成树prim) C.求交集(暴力) F.Call to your teacher(迪杰斯特拉乱用) H.老子的全排列呢(dfs)

菜哭了... A.石油采集 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 链接:https://www.nowcoder.com/acm/contest/76/A来源:牛客网 题目描述 随着海上运输石油泄漏的问题,一个新的有利可图的行业正在诞生,那就是撇油行业.如今,在墨西哥湾漂浮的大量石油,吸引了许多商人的目光.这些商人们有一种特殊的飞机,可以一瓢略过整个海面20米乘10米这么大的长方形.(上下相

ACM_求交集

求交集 Time Limit: 2000/1000ms (Java/Others) Problem Description: 输入集合A和B,按大小顺序输出A和B的交集. Input: 输入包含多组测试数据,每组输入两个整数m,n(1<=m,n<=10^2)分别代表集合A,B的元素个数,再输入集合A,B. Output: 按大小顺序输出A和B的交集. Sample Input: 5 7 80 6 18 44 13 18 39 89 88 6 13 44 Sample Output: 6 13