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

作者:gavenyeah 时间:2022-10-10 17:27:36 

在海量数据中查找出重复出现的元素或者去除重复出现的元素是面试中常考的文图。针对此类问题,可以使用位图法来解决。例如:已知某个文件内包含若干个电话号码,要求统计不同的号码的个数,甚至在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;
 }
}

来源:https://blog.csdn.net/y999666/article/details/51220833

标签:java,bitmap,海量数据,去重,排序
0
投稿

猜你喜欢

  • C#集合之链表的用法

    2022-02-07 13:38:34
  • Java安全框架——Shiro的使用详解(附springboot整合Shiro的demo)

    2022-05-29 09:46:46
  • Maven 错误找不到符号的解决方法

    2021-07-19 09:03:02
  • springboot乱码问题解决方案

    2022-03-22 21:32:38
  • Android Data Binding数据绑定详解

    2023-05-07 14:54:39
  • android layout 按比例布局的代码

    2022-10-11 13:02:40
  • Android实现自动变换大小的ViewPager

    2023-03-19 06:56:15
  • 详解SpringBoot中的统一功能处理的实现

    2022-07-06 12:14:49
  • 关于@Autowired注解和静态方法及new的关系

    2021-07-16 13:08:06
  • Java Fluent Mybatis 项目工程化与常规操作详解流程篇 下

    2021-07-19 11:33:11
  • Bootstrap 下拉菜单.dropdown的具体使用方法

    2023-07-08 19:10:46
  • Android RecyclerView实现下拉刷新和上拉加载

    2023-07-05 21:50:38
  • Android Retrofit 2.0框架上传图片解决方案

    2022-02-23 06:25:27
  • C#实现验证码功能

    2021-11-28 22:20:27
  • Android Studio 3.0 新功能全面解析和旧项目适配问题

    2022-09-16 23:53:57
  • Android提醒微技巧你真的了解Dialog、Toast和Snackbar吗

    2023-03-08 14:15:44
  • Java中String类的常用方法总结

    2021-11-26 10:39:20
  • java利用socket通信实现Modbus-RTU通信协议的示例代码

    2023-05-02 21:37:40
  • Java实现合并多个PDF的示例代码

    2023-04-29 13:25:32
  • Java NIO实现聊天系统

    2023-08-08 08:35:36
  • asp之家 软件编程 m.aspxhome.com