当前位置: 首页 > news >正文

网站页面标题设置公关策划公司

网站页面标题设置,公关策划公司,搜狗搜索推广,潍坊企业网站建设有这样的一个问题: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数 中。 那么我们一般会想到这样做的 1.遍历,时间复杂度O(n) 2.排序(N*logN)&#xff0c…

有这样的一个问题:

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数 中。

那么我们一般会想到这样做的

1.遍历,时间复杂度O(n)

2.排序(N*logN),然后二分查找

那么此时此刻,我们再次细想一下,这些方法一般放在内存中进行的,那么40亿个不重复的无符号整数,有多大容量呢?

首先,10亿个字节大概是1个G

那么10亿个整数大约是4个G

然后呢40亿个整数大约是16个G

所以,如若这么大容量放到电脑内存上跑,恰好此时电脑内存也是16个G,那么不是刚刚好?

其实不然,电脑上不单单只是跑这个程序,后面还有很多,比如微信啊,爱奇艺什么的,所以一般来说,这么大容量放到16G的电脑内存是不太现实的。

那么还有什么解决办法呢?

那就请出今天的主角之一:位图

位图

那么什么又是位图呢?
这里说的位图指的是数据结构当中的,不是那个指图像那个位图哦!

位图:所谓的位图,就是用每一位来存放某种状态的。

适用于海量数据,整数,数据无重复的场景。通常用来判定某个数据存不存在的。

那么举个例子来看看

我这里,假设有了一个字节数组,然后有三个字节,那么一个字节呢,又对应8个比特位

一个比特位呢,又可以代表0/1两种状态。

所以数组arr中,每个数字可以通过某个算式来确定某个位置,然后将某个位置的比特位设置为1,说明,此数字存在。

比如,就11来说

11/8=1

那么我们就放到这个1下标

11%8=3

那么我们就在数组1下标下的第三个比特位设置为1,

然后可以说明数字是存在过的

这里值得注意下,为什么比特位标明的数字从右到左呢?

这里是为了方便,自己也是可以左到右的。

那么回过头细想一下,一个字节有8个比特位,且8个比特位都可以表示状态。

那么10亿个字节大概是0.9G,接近1G

10亿个比特位大概是119兆,看作128兆

那么40亿个比特位,那么就是可以看作512兆。

所以内存量一下子大大缩小了。

那么你看这个位图是不是很强大呢!

ok,那么接下来讲讲如何实现它吧。

由上述刚刚的例子可以看得出,底层还是一个数组来的,而且还是一个字节数组。

然后呢,我们创建它的时候,默认给定一个容量。

但是,有时候,需要用户指定它需要范围是多大,那么可以这样写。

  //位图底层还是一个数组public byte [] elem;//记录存放数据多少public int Usize;public MyBitMap(){//默认给定的数组大小是1个字节this.elem=new byte[1];}public MyBitMap(int n){this.elem=new byte[n/8+1];}

在给定参数的构造方法中,假设我们给定数字范围是10个,那么10/8=1,但是还余下两个,9 10

所以我们直接给多一个字节是可以的。set

那么接着讲讲set吧

set:

思路:

当然这是核心思路,然后代码实现方面还是需要考虑一些细节

比如,我们set方法,参数传入一个数字的话,如若数字给到的是<0的数字,那么此时是不符合我们位图的

再者如果是给定的数字,如若在找数组下标时超出数组范围,这时候也是需要处理的,比如扩容操作。

那么代码如下:

 public void set(int val){if(val<0){//需要抛出异常,因为会导致数组越界throw new IndexOutOfBoundsException();}//放到字节数组哪个位置int arrIndex=val/8;if(arrIndex>elem.length){//超出数组范围,进行扩容elem= Arrays.copyOf(elem,arrIndex+1);}//放到字节数组位置的哪个比特位int bitIndex=val%8;elem[arrIndex] |=(1<<bitIndex);Usize++;}

这个找哪个比特位进行修改,其实最开始时讲过了

即val/8=字节数组哪个下标,

val%8=下标内哪个比特位。

所以这里我们就可以找到,哪个字节哪个比特位要进行修改状态,比如举的例子,设置5这个数字

5/8=0,即在数组0下标

5%8=5,即在比特位第六个位置

get:

这个get方法是返回这个数字是否是存在过的。

所以呢,我们还得是找到这个数字在哪先,然后判断下这个数字的比特位是否是1

举例:

代码:
 

public boolean get(int val){if(val<0){throw new IndexOutOfBoundsException();}int arrIndex=val/8;int bitIndex=val%8;if((elem[arrIndex]&(1<<bitIndex))!=0){return true;}return false;}

reset:

reset方法呢,是把传入参数,对应的比特重新置为0

举例说明:

代码:

 public void reset(int val){if(val<0){throw new IndexOutOfBoundsException();}int arrIndex=val/8;int bitIndex=val%8;elem[arrIndex] &= ~(1<<bitIndex);Usize--;}public int getSize(){return Usize;}

值得注意的是,进行set的时候,Usize++了

所以写一个方法方法来返回当前设置的个数。

那么位图一些基本方法写完了,这里还差最后一个方法:排序

排序

其实我们位图是可以排序的

拿这里来说:

只要我们从右边开始,遍历当前比特位是1的就可以输出当前的值

那么判断当前位是不是为1,是get方法里的思路是一致的,用上&

那么如何输出当前的数字呢?

比如我要输出的是5,那么此时我们可以这样val=i*8+j

当前的i=0,因为我们输出的数字是5,在字节数组的0下标,当j从下标开始遍历,j=5时,就可以输出这个数字5了

代码:
 

 public static void main(String[] args) {int [] arr=new int[]{3,10,9,5,7,24,18};MyBitMap myBitMap=new MyBitMap(24);//先把数据放进字节数组中for(int i=0;i<arr.length;i++){myBitMap.set(arr[i]);}//排序for(int i=0;i< myBitMap.elem.length;i++){for(int j=0;j<8;j++){if((myBitMap.elem[i]&(1<<j))!=0){System.out.print(i*8+j+" ");}}}}

ok,那么位图这里,小编分享的差不多了。

顺带提一句,一开始给的那道题是腾讯曾经的面试题来的。

源码:

public class MyBitMap {//位图底层还是一个数组public byte [] elem;//记录存放数据多少public int Usize;public MyBitMap(){//默认给定的数组大小是1个字节this.elem=new byte[1];}public MyBitMap(int n){this.elem=new byte[n/8+1];}/*** set操作,对添加进来的数据置为1,即为存在的意思* @param val*/public void set(int val){if(val<0){//需要抛出异常,因为会导致数组越界throw new IndexOutOfBoundsException();}//放到字节数组哪个位置int arrIndex=val/8;if(arrIndex>elem.length){//超出数组范围,进行扩容elem= Arrays.copyOf(elem,arrIndex+1);}//放到字节数组位置的哪个比特位int bitIndex=val%8;elem[arrIndex] |=(1<<bitIndex);Usize++;}/*** get方法返回比特位是否设置过1* @param val* @return*/public boolean get(int val){if(val<0){throw new IndexOutOfBoundsException();}int arrIndex=val/8;int bitIndex=val%8;if((elem[arrIndex]&(1<<bitIndex))!=0){return true;}return false;}public void reset(int val){if(val<0){throw new IndexOutOfBoundsException();}int arrIndex=val/8;int bitIndex=val%8;elem[arrIndex] &= ~(1<<bitIndex);Usize--;}public int getSize(){return Usize;}public static void main(String[] args) {int [] arr=new int[]{3,10,9,5,7,24,18};MyBitMap myBitMap=new MyBitMap(24);//先把数据放进字节数组中for(int i=0;i<arr.length;i++){myBitMap.set(arr[i]);}//排序for(int i=0;i< myBitMap.elem.length;i++){for(int j=0;j<8;j++){if((myBitMap.elem[i]&(1<<j))!=0){System.out.print(i*8+j+" ");}}}}
}

http://www.15wanjia.com/news/44871.html

相关文章:

  • 中山做网站哪家专业营业推广的形式包括
  • 上海做网站较好的公司男生最喜欢的浏览器推荐
  • 轻量应用服务器可以做网站吗香飘飘奶茶软文
  • wordpress views插件抖音seo查询工具
  • wordpress做的网站吗百度图片搜索引擎
  • 山东外贸建站seo网站建设公司
  • 什么网站时候做伪静态百度首页网址是多少
  • 龙华、宝安最新通告seo与sem的区别和联系
  • 做网站软件图标是一个箭头的模板网站建站公司
  • 精品课程网站开发的创新点品牌营销策略有哪些方法
  • 网站升级建设百度站长平台账号购买
  • 网站建设制作设计营销公司四川北京最新消息今天
  • html5手机网站制作教程项目优化seo
  • 成都有哪些网站建设seo日常优化内容是什么
  • c 做网站怎么居中网站推广策略有哪些
  • 雅安市建设局网站2022黄页全国各行业
  • 嘉兴高端网站建设产品50个关键词
  • 网站后台管理增加功能站长工具seo综合查询收费吗
  • 用ps做网站页面的大小最近一周新闻热点回顾
  • 泉州网站seo公司北京关键词优化平台
  • 网站建设宗旨是什么百度竞价排名是以什么形式来计费的广告?
  • 设计网站 问题提高工作效率的方法不正确的是
  • 珠海绿网科技有限公司个人seo怎么赚钱
  • 网站利于搜索关键词优化需要从哪些方面开展
  • 做网站的运营维护都要学什么西安seo报价
  • 自己网页制作的目标和受众郑州百度关键词seo
  • 免费推广做产品的网站爱站网影院
  • 旅行网站建设微信软文怎么写
  • 唯品会一个专做特卖的网站广告潍坊今日头条新闻最新
  • 做淘客找单子的网站吉林关键词优化的方法