手机
当前位置:查字典教程网 >编程开发 >C语言 >bloom filter概念讲解以及代码分析
bloom filter概念讲解以及代码分析
摘要:一.简介1.什么是bloomfilter?Bloomfilter是由HowardBloom在1970年提出的二进制向量数据结构,它具有很好的...

一. 简介

1.什么是bloom filter?

Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员,这种检测只会对在集合内的数据错判,而不会对不是集合内的数据进行错判,这样每个检测请求返回有“在集合内(可能错误)”和“不在集合内(绝对不在集合内)”两种情况,可见 Bloom filter 是牺牲了正确率换取时间和空间。

2.bloom filter的计算方法?

如需要判断一个元素是不是在一个集合中,我们通常做法是把所有元素保存下来,然后通过比较知道它是不是在集合内,链表、树都是基于这种思路,当集合内元素个数的变大,我们需要的空间和时间都线性变大,检索速度也越来越慢。 Bloom filter 采用的是哈希函数的方法,将一个元素映射到一个 m 长度的阵列上的一个点,当这个点是 1 时,那么这个元素在集合内,反之则不在集合内。这个方法的缺点就是当检测的元素很多的时候可能有冲突,解决方法就是使用 k 个哈希 函数对应 k 个点,如果所有点都是 1 的话,那么元素在集合内,如果有 0 的话,元素则不在集合内。

3.bloom filter的特点?

Bloom filter 优点就是它的插入和查询时间都是常数,另外它查询元素却不保存元素本身,具有良好的安全性。它的缺点也是显而易见的,当插入的元素越多,错判“在集合内”的概率就越大了,另外 Bloom filter 也不能删除一个元素,因为多个元素哈希的结果可能在 Bloom filter 结构中占用的是同一个位,如果删除了一个比特位,可能会影响多个元素的检测。

二. 代码实现

现下面在linux下实现了bloom filter的功能代码:

复制代码 代码如下:

// bloom.h:

#ifndef __BLOOM_H__

#define __BLOOM_H__

#include<stdlib.h>

typedef unsigned int (*hashfunc_t)(const char *);

typedef struct {

size_t asize;

unsigned char *a;

size_t nfuncs;

hashfunc_t *funcs;

} BLOOM;

BLOOM *bloom_create(size_t size, size_t nfuncs, ...);

int bloom_destroy(BLOOM *bloom);

int bloom_add(BLOOM *bloom, const char *s);

int bloom_check(BLOOM *bloom, const char *s);

#endif

// bloom.c:

#include<limits.h>

#include<stdarg.h>

#include"bloom.h"

#define SETBIT(a, n) (a[n/CHAR_BIT] |= (1<<(n%CHAR_BIT)))

#define GETBIT(a, n) (a[n/CHAR_BIT] & (1<<(n%CHAR_BIT)))

BLOOM *bloom_create(size_t size, size_t nfuncs, ...)

{

BLOOM *bloom;

va_list l;

int n;

if(!(bloom=malloc(sizeof(BLOOM)))) return NULL;

if(!(bloom->a=calloc((size+CHAR_BIT-1)/CHAR_BIT, sizeof(char)))) {

free(bloom);

return NULL;

}

if(!(bloom->funcs=(hashfunc_t*)malloc(nfuncs*sizeof(hashfunc_t)))) {

free(bloom->a);

free(bloom);

return NULL;

}

va_start(l, nfuncs);

for(n=0; n<nfuncs; ++n) {

bloom->funcs[n]=va_arg(l, hashfunc_t);

}

va_end(l);

bloom->nfuncs=nfuncs;

bloom->asize=size;

return bloom;

}

int bloom_destroy(BLOOM *bloom)

{

free(bloom->a);

free(bloom->funcs);

free(bloom);

return 0;

}

int bloom_add(BLOOM *bloom, const char *s)

{

size_t n;

for(n=0; n<bloom->nfuncs; ++n) {

SETBIT(bloom->a, bloom->funcs[n](s)%bloom->asize);

}

return 0;

}

int bloom_check(BLOOM *bloom, const char *s)

{

size_t n;

for(n=0; n<bloom->nfuncs; ++n) {

if(!(GETBIT(bloom->a, bloom->funcs[n](s)%bloom->asize))) return 0;

}

return 1;

}

// test.c:

#include<stdio.h>

#include<string.h>

#include"bloom.h"

//下面为两种哈希算法函数

unsigned int sax_hash(const char *key)

{

unsigned int h=0;

while(*key) h^=(h<<5)+(h>>2)+(unsigned char)*key++;

return h;

}

unsigned int sdbm_hash(const char *key)

{

unsigned int h=0;

while(*key) h=(unsigned char)*key++ + (h<<6) + (h<<16) - h;

return h;

}

int main(int argc, char *argv[])

{

FILE *fp;

char line[1024];

char *p;

BLOOM *bloom;

if(argc<2) {

fprintf(stderr, "ERROR: No word file specifiedn");

return EXIT_FAILURE;

}

if(!(bloom=bloom_create(2500000, 2, sax_hash, sdbm_hash))) {

fprintf(stderr, "ERROR: Could not create bloom filtern");

return EXIT_FAILURE;

}

if(!(fp=fopen(argv[1], "r"))) {

fprintf(stderr, "ERROR: Could not open file %sn", argv[1]);

return EXIT_FAILURE;

}

while(fgets(line, 1024, fp)) {

if((p=strchr(line, 'r'))) *p='';//回车

if((p=strchr(line, 'n'))) *p='';//换行

bloom_add(bloom, line);

}

fclose(fp);

while(fgets(line, 1024, stdin)) {

if((p=strchr(line, 'r'))) *p='';

if((p=strchr(line, 'n'))) *p='';

p=strtok(line, " t,.;:rn?!-/()");

while(p) {

if(!bloom_check(bloom, p)) {

printf("No match for ford "%s"n", p);

}

else

printf("match for ford "%s"n",p);

p=strtok(NULL, " t,.;:rn?!-/()");

}

}

bloom_destroy(bloom);

return EXIT_SUCCESS;

}

// Makefile:

all: bloom

bloom: bloom.o test.o

cc -o bloom -Wall -pedantic bloom.o test.o

bloom.o: bloom.c bloom.h

cc -o bloom.o -Wall -pedantic -ansi -c bloom.c

test.o: test.c bloom.h

cc -o test.o -Wall -pedantic -ansi -c test.c

【bloom filter概念讲解以及代码分析】相关文章:

C++ sizeof 实例解析

linux c多线程编程实例代码

C语言 实现N阶乘的程序代码

do...while(0)的妙用详细解析

深入理解goto语句的替代实现方式分析

sizeof()的简单介绍

基于C程序启动代码的深入分析

简单的汉诺塔问题解法代码

深入理解堆排序及其分析

char str[] 与 char *str的区别详细解析

精品推荐
分类导航