비트 맵 과 부 릉 필터
17439 단어 데이터 구조
. h 파일
#pragma once
#include
typedef uint64_t BitmapType;
#define BitmapMaxSize 1000
typedef struct Bitmap
{
uint64_t* data;
uint64_t capacity;//
}Bitmap;
//
void BitmapInit(Bitmap* bm,uint64_t capacity);
//
void BitmapDestroy(Bitmap* bm);
// 1
void BitmapSet(Bitmap* bm,uint64_t index);
// 0
void BitmapUnset(Bitmap* bm,uint64_t index);
// 1
void BitmapFill(Bitmap* bm);
// 0
void BitmapClear(Bitmap* bm);
// 1
int BitmapTest(Bitmap* bm,uint64_t index);
(1) 비트 맵 의 한 사람 이 1 인지 확인 합 니 다.
int BitmapTest(Bitmap* bm,uint64_t index)
{
if(bm == NULL || index >= bm->capacity)
{
//
return 0;
}
uint64_t n,offset;
GetOffset(index,&n,&offset);
uint64_t ret = bm->data[n] & (0x1ul << offset);
return ret > 0 ? 1 : 0;
}
(2) 비트 맵 의 모든 비트 를 0 으로 설정
void BitmapClear(Bitmap* bm)
{
if(bm == NULL)
{
return;
}
uint64_t size = Getsize(bm->capacity);
memset(bm->data,0x0,(sizeof(BitmapType)*size));
return;
}
(3) 비트 맵 초기 화
uint64_t Getsize(uint64_t capacity)
{
uint64_t size = capacity / (sizeof(BitmapType)*8)+1;
return size;
}
void BitmapInit(Bitmap* bm,uint64_t capacity)
{
if(bm == NULL)
{
return;
}
//capacity
// capacity = 100,2
// capacity = 200,4
// capacity = 300,5
// capacity = N,N/(sizeof(uint64_t) * 8)+ 1
bm->capacity = capacity;
//size
uint64_t size = Getsize(capacity);
bm->data = (BitmapType*)malloc(sizeof(BitmapType)*size);
memset(bm->data,0,sizeof(BitmapType)*size);
return;
}
(4) 비트 맵 삭제
void BitmapDestroy(Bitmap* bm)
{
if(bm == NULL)
{
return;
}
bm->capacity = 0;
free(bm->data);
return;
}
(5) 비트 맵 의 한 분 을 1 로 설정 합 니 다.
void GetOffset(uint64_t index,uint64_t* n,uint64_t* offset)
{
*n = index / (sizeof(BitmapType)*8);
*offset = index % (sizeof(BitmapType)*8);
return;
}
void BitmapSet(Bitmap* bm,uint64_t index)
{
if(bm == NULL || index >= bm->capacity)
{
return;
}
uint64_t n,offset;
GetOffset(index,&n,&offset);
bm->data[n] |= (0x1ul << offset);
return;
}
void TestSet()
{
TEST_HEADER;
Bitmap bm;
BitmapInit(&bm,100);
BitmapSet(&bm,50);
int ret = BitmapTest(&bm,50);
printf("ret expected 1,actual %d
",ret);
ret = BitmapTest(&bm,20);
printf("ret expected 0,actual %d
",ret);
}
(6) 비트 맵 의 한 분 을 0 으로 설정 합 니 다.
void BitmapUnset(Bitmap* bm,uint64_t index)
{
if(bm == NULL || index >= bm->capacity)
{
return;
}
uint64_t n,offset;
GetOffset(index,&n,&offset);
bm->data[n] &= ~(0x1ul << offset);
return;
}
void TestUnset()
{
TEST_HEADER;
Bitmap bm;
BitmapInit(&bm,100);
BitmapSet(&bm,50);
int ret = BitmapTest(&bm,50);
printf("ret expected 1,actual %d
",ret);
BitmapUnset(&bm,50);
ret = BitmapTest(&bm,50);
printf("ret expected 0,actual %d
",ret);
}
(7) 비트 맵 의 모든 비트 를 1 로 설정
void TestFill()
{
TEST_HEADER;
Bitmap bm;
BitmapInit(&bm,100);
BitmapFill(&bm);
int ret = BitmapTest(&bm,50);
printf("ret expected 1,actual %d
",ret);
ret = BitmapTest(&bm,0);
printf("ret expected 1,actual %d
",ret);
ret = BitmapTest(&bm,99);
printf("ret expected 1,actual %d
",ret);
}
void BitmapFill(Bitmap* bm)
{
if(bm == NULL)
{
return;
}
uint64_t size = Getsize(bm->capacity);
memset(bm->data,0xff,(sizeof(BitmapType)*size));
return;
}
2. 부 릉 필터 구현
. h 파일
#pragma once
#include"bitmap.h"
// ,
typedef uint64_t (*BloomHash)(const char*);
#define BloomHashCount 2
typedef struct BloomFilter
{
Bitmap bm;
BloomHash bloom_hash[BloomHashCount];
}BloomFilter;
void BloomFilterInit(BloomFilter* bf);
void BloomFilterDestroy(BloomFilter* bf);
void BloomFilterInsert(BloomFilter* bf,const char* str);
int BloomFilterIsExist(BloomFilter* bf,const char* str);
(1)hash_func.c
#include
#include
size_t BKDRHash(const char* str)
{
size_t hash = 0;
size_t ch = 0;
while(ch = (size_t)*str++)
{
hash = hash * 131 +ch;
}
return hash;
}
size_t SDBMHash(const char* str)
{
size_t hash = 0;
size_t ch = 0;
while(ch = (size_t)*str++)
{
hash = hash * 65599 +ch;
}
return hash;
}
(2) 부 릉 필터 초기 화
void BloomFilterInit(BloomFilter* bf)
{
if(bf == NULL)
{
return;
}
BitmapInit(&bf->bm,10000);
bf->bloom_hash[0] = SDBMHash;
bf->bloom_hash[1] = BKDRHash;
return;
}
(3) 부 릉 필터 소각
void BloomFilterDestroy(BloomFilter* bf)
{
if(bf == NULL)
{
return;
}
bf->bloom_hash[0] = NULL;
bf->bloom_hash[1] = NULL;
BitmapDestroy(&bf->bm);
return;
}
(4) 부 릉 필터 에 문자열 삽입
void BloomFilterInsert(BloomFilter* bf,const char* str)
{
if(bf == NULL || str == NULL)
{
//
return;
}
size_t i = 0;
for(;i < BloomHashCount;++i)
{
uint64_t hash = bf->bloom_hash[i](str) % BitmapMaxSize;
BitmapSet(&bf->bm,hash);
}
return;
}
(5) 부 릉 필터 에 문자열 이 있 는 지 확인 하기
int BloomFilterIsExist(BloomFilter* bf,const char* str)
{
if(bf == NULL || str == NULL)
{
//
return 0;
}
size_t i = 0;
for(;i < BloomHashCount;++i)
{
uint64_t hash = bf->bloom_hash[i](str) % BitmapMaxSize;
int ret = BitmapTest(&bf->bm,hash);
if(ret == 0)
{
return 0;
}
}
return 1;
}
(6) 전체 테스트 함수
void TestBloom()
{
TEST_HEADER;
BloomFilter bf;
BloomFilterInit(&bf);
BloomFilterInsert(&bf,"nihao");
BloomFilterInsert(&bf,"haha");
int ret = BloomFilterIsExist(&bf,"nihao");
printf("ret expected 1,actual %d
",ret);
ret = BloomFilterIsExist(&bf,"hehe");
printf("ret expected 0,actual %d
",ret);
}
위 에 있 는 이 부 릉 알고리즘 은 공간 을 절약 하지만 삭제 알고리즘 을 지원 하지 않 습 니 다. 위 에 있 는 알고리즘 은 한 위치 에 몇 개의 수 를 매 핑 했 을 수 있 기 때문에 한 개의 수 를 삭제 하면 다른 수 에 영향 을 줄 수 있 습 니 다.
만약 에 우리 가 삭제 알고리즘 을 사용 하려 면 인용 계수 방법 을 사용 할 수 있 습 니 다. 그러면 하나의 수 를 저장 하 는 위 치 는 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트 비트
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.