• 布隆过滤器(Bloom Filter)的C语言实现


    前文《布隆过滤器(Bloom Filter)详解》主要讲了布隆过滤器(Bloom Filter)的基本原理和相关应用,本文将使用 C 语言实现一个简单的布隆过滤器(Bloom Filter)。

    http://en.literateprograms.org/Bloom_filter_(C)?oldid=17386

    #ifndef __BLOOM_FILTER_H__
    #define __BLOOM_FILTER_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
    #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;
    }

    测试文件:

    #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 specified\n");
            return EXIT_FAILURE;
        }
    
        if(!(bloom=bloom_create(2500000, 2, sax_hash, sdbm_hash))) {
            fprintf(stderr, "ERROR: Could not create bloom filter\n");
            return EXIT_FAILURE;
        }
    
        if(!(fp=fopen(argv[1], "r"))) {
            fprintf(stderr, "ERROR: Could not open file %s\n", argv[1]);
            return EXIT_FAILURE;
        }
    
        while(fgets(line, 1024, fp)) {
            if((p=strchr(line, '\r'))) *p='\0';
            if((p=strchr(line, '\n'))) *p='\0';
    
            bloom_add(bloom, line);
        }
    
        fclose(fp);
    
        while(fgets(line, 1024, stdin)) {
            if((p=strchr(line, '\r'))) *p='\0';
            if((p=strchr(line, '\n'))) *p='\0';
    
            p=strtok(line, " \t,.;:\r\n?!-/()");
            while(p) {
                if(!bloom_check(bloom, p)) {
                    printf("No match for ford \"%s\"\n", p);
                }
                p=strtok(NULL, " \t,.;:\r\n?!-/()");
            }
        }
    
        bloom_destroy(bloom);
    
        return EXIT_SUCCESS;
    }
  • 相关阅读:
    json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
    Java中时间与时间戳的转换
    python爬取网页数据
    selenium爬取网页内容知识点总结(代码均亲测可用)
    【LeetCode 5】 最长回文子串
    【LeetCode 4】寻找两个有序数组的中位数
    【LeetCode 3】无重复字符的最长子串
    【LeetCode 1】两数之和
    【LeetCode 2】两数相加
    【3-4】数字三角形问题
  • 原文地址:https://www.cnblogs.com/haippy/p/2590669.html
Copyright © 2020-2023  润新知