海量数据去重排序bitmap(位图法)在java中实现的两种方法

 更新时间:2019年02月18日 09:18:43   作者:gavenyeah  
今天小编就为大家分享一篇关于海量数据去重排序bitmap(位图法)在java中实现的两种方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

在海量数据中查找出重复出现的元素或者去除重复出现的元素是面试中常考的文图。针对此类问题,可以使用位图法来解决。例如:已知某个文件内包含若干个电话号码,要求统计不同的号码的个数,甚至在O(n)时间复杂度内对这些号码进行排序。

位图法需要的空间很少(依赖于数据分布,但是我们也可以通过一些放啊发对数据进行处理,使得数据变得密集),在数据比较密集的时候效率非常高。例如:8位整数可以表示的最大十进制数值为99999999,如果每个数组对应于一个bit位,那么把所有的八进制整数存储起来只需要:99Mbit = 12.375MB.

实际上,java jdk1.0已经提供了bitmap的实现BitSet类,不过其中的某些方法是jdk1.4之后才有的。

下面我先自己实现一下bitmap 的原理,然后再直接调用jdk的BitSet类分别实现bitmap, 方便比较理解:

package swordoffer;
//去除重复并排序
import java.util.Arrays;
import java.util.BitSet;
import java.util.Random;
/**
 * @author Gavenyeah
 * @date Time:
 * @des:
 */
public class BitMap {
  int ARRNUM = 800;
  int LEN_INT = 32;
  int mmax = 9999;
  int mmin = 1000;
  int N = mmax - mmin + 1;
  public static void main(String args[]) {
     new BitMap().findDuplicate();
    new BitMap().findDup_jdk();
  }
  public void findDup_jdk() {
    System.out.println("*******调用JDK中的库方法--开始********");
    BitSet bitArray = new BitSet(N);
    int[] array = getArray(ARRNUM);
    for (int i = 0; i < ARRNUM; i++) {
      bitArray.set(array[i] - mmin);
    }
    int count = 0;
    for (int j = 0; j < bitArray.length(); j++) {
      if (bitArray.get(j)) {
        System.out.print(j + mmin + " ");
        count++;
      }
    }
    System.out.println();
    System.out.println("排序后的数组大小为:" + count );
    System.out.println("*******调用JDK中的库方法--结束********");
  }
  public void findDuplicate() {
    int[] array = getArray(ARRNUM);
    int[] bitArray = setBit(array);
    printBitArray(bitArray);
  }
  public void printBitArray(int[] bitArray) {
    int count = 0;
    for (int i = 0; i < N; i++) {
      if (getBit(bitArray, i) != 0) {
        count++;
        System.out.print(i + mmin + "\t");
      }
    }
    System.out.println();
    System.out.println("去重排序后的数组大小为:" + count);
  }
  public int getBit(int[] bitArray, int k) {// 1右移 k % 32位 与上 数组下标为 k/32 位置的值
    return bitArray[k / LEN_INT] & (1 << (k % LEN_INT));
  }
  public int[] setBit(int[] array) {// 首先取得数组位置下标 i/32, 然后 或上
                    // 在该位置int类型数值的bit位:i % 32
    int m = array.length;
    int bit_arr_len = N / LEN_INT + 1;
    int[] bitArray = new int[bit_arr_len];
    for (int i = 0; i < m; i++) {
      int num = array[i] - mmin;
      bitArray[num / LEN_INT] |= (1 << (num % LEN_INT));
    }
    return bitArray;
  }
  public int[] getArray(int ARRNUM) {
    @SuppressWarnings("unused")
    int array1[] = { 1000, 1002, 1032, 1033, 6543, 9999, 1033, 1000 };
    int array[] = new int[ARRNUM];
    System.out.println("数组大小:" + ARRNUM);
    Random r = new Random();
    for (int i = 0; i < ARRNUM; i++) {
      array[i] = r.nextInt(N) + mmin;
    }
    System.out.println(Arrays.toString(array));
    return array;
  }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:

相关文章

  • SpringBoot服务端数据校验过程详解

    SpringBoot服务端数据校验过程详解

    这篇文章主要介绍了SpringBoot服务端数据校验过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Spring中Bean对象的定义、注册和获取流程分析

    Spring中Bean对象的定义、注册和获取流程分析

    这篇文章主要介绍了Spring中Bean对象的定义、注册和获取流程分析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • springboot整合腾讯云短信开箱即用的示例代码

    springboot整合腾讯云短信开箱即用的示例代码

    这篇文章主要介绍了springboot整合腾讯云短信开箱即用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Mybatis的@select和@SelectProvider注解方式动态SQL语句解读

    Mybatis的@select和@SelectProvider注解方式动态SQL语句解读

    这篇文章主要介绍了Mybatis的@select和@SelectProvider注解方式动态SQL语句,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • 使用Java实现将ppt转换为文本

    使用Java实现将ppt转换为文本

    这篇文章主要为大家详细介绍了如何使用Java实现将ppt转换为文本,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2024-01-01
  • java JDBC系列教程之JDBC类的简析与JDBC的基础操作

    java JDBC系列教程之JDBC类的简析与JDBC的基础操作

    这篇文章主要介绍了java JDBC系列教程之JDBC类的简析与JDBC的基础操作,本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • java使用Jsoup组件生成word文档

    java使用Jsoup组件生成word文档

    java使用Jsoup组件生成word文档的方法
    2013-11-11
  • java stringbuffer的用法示例

    java stringbuffer的用法示例

    这篇文章主要介绍了java stringbuffer的用法示例,字符串缓冲区,是一个容器(当返回到的是String时而且长度不确定,数据类型不确定时就可以用StringBuffer)其实底层还是数组,只是被封装了,对外提供了方法,初始容量为16个字符
    2014-01-01
  • IDEA2022搭建Spring Cloud多模块项目的详细过程

    IDEA2022搭建Spring Cloud多模块项目的详细过程

    这篇文章主要介绍了IDEA2022搭建Spring Cloud多模块项目,网上有很多教程父模块都是通过maven的方式创建的,然后子模块是通过Spring Initalizr方式创建,这种方式父模块无法管理子模块的依赖仲裁,需要每个子模块自行管理,就失去了父模块的用处了
    2022-10-10
  • Java设计模式中的门面模式详解

    Java设计模式中的门面模式详解

    门面模式又叫外观模式(Facade Pattern),主要用于隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口,本文通过实例代码给大家介绍下java门面模式的相关知识,感兴趣的朋友一起看看吧
    2022-09-09

最新评论