1. 程式人生 > >點陣圖法介紹

點陣圖法介紹

一、定義
點陣圖法就是bitmap的縮寫。所謂bitmap,就是用每一位來存放某種狀態,適用於大規模資料,但資料狀態又不是很多的情況。通常是用來判斷某個資料存不存在的。在STL中有一個bitset容器,其實就是點陣圖法

資料結構

unsigned int bit[N];

在這個數組裡面,可以儲存 N*sizeof(int)*8個數據,但是最大的數只能是N*sizeof(int)*8-1

相關操作

寫入資料

定義一個數組: unsigned char bit[8*1024];這樣做,能存 8K*8=64K 個 unsigned short 資料。

bit 存放的位元組位置和位位置(位元組0~8191,位 0~7 )比如寫1234,位元組序:1234/8 = 154; 位序: 1234 &0b111 = 2 ,那麼 1234 放在 bit 的下標 154 位元組處,把該位元組的 2 號位( 0~7)置為 1。

位元組位置: int nBytePos =1234/8 = 154;
位位置:   int nBitPos = 1234 & 7 = 2;
比如寫入 1236 ,
位元組位置: int nBytePos =1236/8 = 154;
位位置:   int nBitPos = 1236 & 7 = 4

// / 把陣列的 154 位元組的 4 位置為 1  
val = 1<<nBitPos;  
arrBit[nBytePos] = arrBit[nBytePos] |val;  // 再寫入 1236 得到arrBit[154]=0b00010100  

程式碼實現

/* Copyright (C) 1999 Lucent Technologies */
/* From 'Programming Pearls' by Jon Bentley */
/* bitsort.c -- bitmap sort from Column 1 * Sort distinct integers in the range [0..N-1] */ 
#include <stdio.h> 
#define BITSPERWORD 32 
#define SHIFT 5 
#define MASK 0x1F 
#define N 10000000 
int a[1 + N/BITSPERWORD]; 
/*
i是int型別,32位的,而a是int型陣列,所以除以32可以知道是在a的陣列中哪一個下標,模32可以確定某一位。
a[i>>SHIFT]是第i位應該在第幾個int上,右移5位相當於除2^5也就是32
(1<<(i & MASK))是第i位在該int上的第幾個bit,i & 0x1F 保留了低五位,相當於模32.
*/
void set(int i) { //將指定的bit賦1
    a[i>>SHIFT] |= (1<<(i & MASK)); 
} 

void clr(int i) { //將指定的bit清0
    a[i>>SHIFT] &= ~(1<<(i & MASK)); 
} 

int test(int i){//取一下存入的值  每5 bit是一組。
    return a[i>>SHIFT] & (1<<(i & MASK)); 
} 
int main() { 
    int i; 
    for (i = 0; i < N; i++) 
        clr(i); //每位設為0,
    /*
    根據輸入的i ,放入指定位置,對應的位置為1
    比如你輸入,4,2,3,1
        4:0000000000010000
        2:0000000000010100
        3:0000000000011100
        1:0000000000011110
    */
    while (scanf("%d", &i) != EOF) 
        set(i); 
    //遍歷所有位,從bit0~~~bit N判斷該位是不是0,如果不是0的話,就有數,作輸出,相當於排序。
    for (i = 0; i < N; i++) 
        if (test(i)) 
           printf("%d\n", i);
    return 0; 
}
  • 使用點陣圖法判斷整形陣列是否存在重複遍歷陣列,一個一個放入bitmap,並且檢查其是否在bitmap中出現過,如果沒出現放入,否則即為重複的元素。