文档章节

浪客剑心:位图法Bitmap算法分析

 木宛城主
发布于 2015/03/02 19:39
字数 831
阅读 5
收藏 0

看了博客园里一篇文章《一道腾讯前端试题,谁来试试身手》,正好以前了解过位图法,确实不错。位图法适用于大规模数据,但数据状态又不是很多的情况。通常是用来判断某个数据存不存在,如可标记1为存在,0为不存在。

  位图法网上资料比较少,我在百度百科找到了对它的描述


位图法比较适合于如下这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数,遇到几就给新数组的第几位置上1,如遇到 5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况为2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。

 

  效率测试(参考一道腾讯前端试题,谁来试试身手):

  传统的双重循环查找也是可取的,但效率实在不敢恭维,特别是处理大量数据时候

  

class Program
    {
        static void Main(string[] args)
        {

            //产生随机数
            int[] array = Enumerable.Range(1, 100000).OrderBy
(n => Guid.NewGuid()).Take(80000).ToArray();
      
            DateTime dt1 = DateTime.Now;

            int max = array[0];
            int flag;
            //数组无序排列,查找最大值
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i] > max)
                {
                    max = array[i];
                }
            }
            for (int i = 1; i <= max; i++)
            {
                flag = 1;
                for (int j = 0; j < array.Length; j++)
                {
                    //相等标记Flag=0,意味着不是缺少的数字
                    if (i.Equals(array[j]))
                    {
                        flag = 0;
                        break;
                    }

                }
                if (flag == 1)
                {
                    Console.Write("{0},", i);
                }

            }
            DateTime dt2 = DateTime.Now;
            TimeSpan ts = dt2 - dt1;
            Console.WriteLine("\r\n" + "共耗时间{0}ms", ts.TotalMilliseconds);//52730.5525
            Console.ReadKey();
        }
    }

测试结果:数据量小时,还OK,数据量大的情况下,显示很卡很缓慢,最坏的时间复杂度:T(n)=O(n*n)

以上测试,总时间约为:51291.2996MS

位图法测试

class Program
    {
        static void Main(string[] args)
        {


            //随即产生80000个不重复数
            int[] array = Enumerable.Range(1, 100000).OrderBy
(n => Guid.NewGuid()).Take(80000).ToArray();
          
            //int[] array={1,2,3,5,7,9,10,12,45,62,55,78,98,52,12,4,200,60,63,65,66,67,68,69,70,74,79,80,82,89,90,91,92,93,94,98,100,101};
            DateTime dt1=DateTime.Now;
            
            //找出最大值
            int max=array[0];
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i]>max)
                {
                    max = array[i];
                }
            }
            //新数组的长度为旧数组最大数字+1
            int[] lose=new int[max+1];
            foreach (int item in array)
            {
                //若Item为2,则Lose[2]=1...所以新数组的长度为旧数组最大数字+1
                lose[item] = 1;
            }
            //那么为0的就是缺少值
            for (int i = 1; i < lose.Length; i++)//100
            {
                if (lose[i].Equals(0))
                {
                    Console.Write("{0},",i);
                }
            }
            DateTime dt2=DateTime.Now;
            Console.WriteLine("\r\n"+(dt2-dt1).TotalMilliseconds);//6004.3379Ms
            Console.ReadKey();

        }
    }

位图法在确定最大数值后的时间复杂度还是挺乐观的,最坏情况:T(n)=O(2n)

屏幕飞快的刷新着,测试时间约是:6295.3601MS

总结

判断集合中是否存在重复元素或者查找缺失元素是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可,位图法Bitmap可以考虑。

© 著作权归作者所有

共有 人打赏支持
粉丝 2
博文 222
码字总数 199010
作品 0
黄浦
私信 提问
大数据处理算法一:Bitmap算法

腾讯面试题:给20亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中并且所耗内存尽可能的少? 解析:bitmap算法就好办多了 所谓bitmap,...

超人学院
2015/04/29
0
2
RT-Thread的位图调度算法分析

RT-Thread的内核调度算法 rt-thread的调度算法为基于优先级调度和基于时间片轮转调度共存的策略。rt-thread内核中存在多个线程优先级,并且支持多个线程具有同样的线程优先级。线程级别数目在...

RTThread物联网操作系统
07/31
0
0
如何判断一个数是否在40亿个整数中

【面试现场】 题目:我有40亿个整数,再给一个新的整数,我需要判断新的整数是否在40亿个整数中,你会怎么做? 【请教大神】 小史回到学校,把面试的情况和计算机学院的吕老师说了一下。 小史...

Ocean_K
09/05
0
0
华山论剑数据之巅—畅谈大数据Meetup第一期

伴随着物联网、移动互联网、云计算的快速发展,全球数据总量更是以每年超过40%的速度成长,几乎每两年就翻一番。大数据实现从数据到价值的高效转化,也衍生了无数基于大数据的平台和商机。 ...

瀚德FinTech创新学院
2017/05/13
3
0
【BAT面试现场】如何判断一个数是否在40亿个整数中?

点击上方“程序人生”,选择“置顶公众号” 第一时间关注程序猿(媛)身边的故事 作者 channingbreeze 如需转载,请联系原作者授权。 小史是一个应届生,虽然学的是电子专业,但是自己业余时...

CSDN程序人生
08/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

EOS docker开发环境

使用eos docker镜像是部署本地EOS开发环境的最轻松愉快的方法。使用官方提供的eos docker镜像,你可以快速建立一个eos开发环境,可以迅速启动开发节点和钱包服务器、创建账户、编写智能合约....

汇智网教程
今天
12
0
《唐史原来超有趣》的读后感优秀范文3700字

《唐史原来超有趣》的读后感优秀范文3700字: 作者:花若离。我今天分享的内容《唐史原来超有趣》这本书的读后感,我将这本书看了一遍之后就束之高阁了,不过里面的内容一直在在脑海中回放,...

原创小博客
今天
19
0
IC-CAD Methodology知识图谱

CAD (Computer Aided Design),计算机辅助设计,指利用计算机及其图形设备帮助设计人员进行设计工作,这个定义同样可以用来近似描述IC公司CAD工程师这个岗位的工作。 早期IC公司的CAD岗位最初...

李艳青1987
今天
19
0
CompletableFuture get方法一直阻塞或抛出TimeoutException

问题描述 最近刚刚上线的服务突然抛出大量的TimeoutException,查询后发现是使用了CompletableFuture,并且在执行future.get(5, TimeUnit.SECONDS);时抛出了TimeoutException异常,导致接口响...

xiaolyuh
今天
9
0
dubbo 搭建与使用

官网:http://dubbo.apache.org/en-us/ 一,安装监控中心(可以不安装) admin管理控制台,monitor监控中心 下载 bubbo ops 这个是新版的,需要node.js环境,我没有就用老版的了...

小兵胖胖
今天
20
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部