대용량 데이터 처리를위한 비트 맵

 빅 데이터에 대해 말하는 버닝 컵 

영상

I. 개요

이 기사에서는 Bit-Map 알고리즘의 관련 원리와 Bit-Map 알고리즘의 일부 사용 시나리오에 대해 설명합니다. 예를 들어 BitMap은 대용량 데이터의 중복을 찾고 개별 요소가 대용량 데이터에 있는지 판단하는 문제를 해결합니다. 마지막으로 BitMap의 특성은 다양한 시나리오에서 소개되었습니다.

Two, Bit-Map 알고리즘

이러한 시나리오를 먼저 살펴 보겠습니다. 2G 메모리가있는 일반 PC의 경우 반복되지 않고 정렬되지 않은 40 억 개의 부호없는 정수를 처리해야합니다. 정수를 제공하고이 정수를 빠르게 판단 할 수 있는지 물어보십시오. . 파일에있는 40 억 개의 데이터에 속합니까?

질문 사고 :

40 억 개의 정수가 (40 억 * 4) / 1024 / 1024 / 1024를 차지하는데, 이는 약 14.9G입니다. 분명히 메모리는 2G에 불과하여 맞지 않습니다. 따라서이 40 억 데이터를 넣는 것은 불가능합니다. 계산을위한 기억. 이 문제를 빠르게 해결하는 가장 좋은 해결책은 데이터를 메모리에 저장하는 것이므로 이제 문제는 2G 메모리 공간 내에 40 억 개의 정수를 저장하는 방법입니다. int 정수는 Java에서 4 바이트, 즉 32 비트를 차지합니다. int 정수를 식별하는 데 비트를 사용할 수 있으면 저장 공간이 크게 줄어 듭니다. 40 억 정수에 필요한 메모리 공간을 40 억 / 8 /로 계산합니다. 1024/1024는 약 476.83MB이므로 처리를 위해이 40 억 정수를 메모리에 넣을 수 있습니다.

구체적인 아이디어 :

1 int는 4 바이트, 즉 4 * 8 = 32 비트를 차지합니다. 그러면 이러한 데이터를 저장하기 위해 int tmp [1 + N / 32] 길이의 int 배열 만 적용하면됩니다. 여기서 N은 총 수를 나타냅니다. tmp의 각 요소는 10 진수 0 ~ 31에 해당 할 수있는 32 비트를 포함하므로 BitMap 테이블을 얻을 수 있습니다.

tmp [0] : 0 ~ 31을 나타낼 수 있습니다.

tmp [1] : 32 ~ 63을 나타낼 수 있습니다.

tmp [2]는 64 ~ 95를 나타낼 수 있습니다.

.......

그런 다음 십진수가 해당 비트 위치로 어떻게 변환되는지 살펴 보겠습니다.

40 억 int 데이터가 6,3,8,32,36, ...이라고 가정하면 특정 BitMap은 다음과 같이 표현됩니다.

영상

tmp 배열에있는 int 숫자의 첨자를 확인하는 방법은 실제로 32로 직접 나누어 정수 부분을 구하여 얻을 수 있습니다. 예를 들어, 정수 8을 32로 나눈 정수는 0으로 반올림 한 다음 8은 tmp에 있습니다. [0]. 또한 8의 32 비트 중 tmp [0]에있는 것이 무엇인지 어떻게 알 수 있습니까?이 경우 직접 mod 32는 괜찮습니다. 정수 8과 마찬가지로 32는 tmp [0] 8의 8 번째 mod와 같습니다. , 정수 8은 tmp [0]의 8 번째 비트 (오른쪽부터 계산)에 있습니다.

자바로 구현 한 것은 비트 셋 (bitset)으로 오랫동안 존재해온 도구이며, 구체적인 용도는 다음 소스 코드를 참고할 수 있습니다.

import java.util.BitSet;

public class BitSetTest {

   public static void main(String[] args{
       int [] array = new int [] {1,2,3,22,0,3,63};
       BitSet bitSet  = new BitSet(1);
       System.out.println(bitSet.size());   //64
       bitSet  = new BitSet(65);
       System.out.println(bitSet.size());   //128
       bitSet  = new BitSet(23);
       System.out.println(bitSet.size());   //64

       //将数组内容组bitmap
       for(int i=0;i<array.length;i++)
       {
           bitSet.set(array[i], true);
       }

       System.out.println(bitSet.get(22));
       System.out.println(bitSet.get(60));

       System.out.println("下面开始遍历BitSet:");
       for ( int i = 0; i < bitSet.size(); i++ ){
           System.out.println(bitSet.get(i));
       }
   }

}

물론 이것은 기성품의 사용이며 직접 작성하는 것이 매우 간단하며 아래에 간단한 구현이 있습니다.

{
    [] (길이) {
        . = 길이 = [() (길이 >>) + ((길이 &)>? :)]}

    (인덱스) {
        = [() ((인덱스-) >>)] = () ((인덱스-) &) >> &}


    (인덱스) {
        = () ((인덱스-) >>) = () ((인덱스-) &) = [] [] = | (<<)}
    ([] 인수) {
        = BitMap (). setBit () .. println (.getBit ()) .. println (.getBit ())}
}


추천

출처blog.51cto.com/15127544/2665518