海量字符串查找

来源:互联网 发布:python 运维监控系统 编辑:程序博客网 时间:2024/05/16 17:21

这次老师留的作业是海量字符串查找

很多同学用了trie树,压缩了trie树,作为一个菜鸟,我和我的搭档选择了比较简单的bloomfilter,她写出来代码之后我读了再看着她的写的,很惭愧,不过自己也进步了一点

继续努力吧

老师给了一个strpool.dat的文件,里面是很多邮箱地址,还有一个checkedemai.dat的文件,里面是100个邮箱,我们需要查明这100个邮箱在strpool中是不是存在

存在就把yes写入新文件,不存在就写入no

1)这次我学到了怎么在C语言中打开一个文件,以写的方式还是读的方式

用FILE定义三个指针,指向三个文件,再用fopen函数打开文件:

FILE *fp_strpool, *fp_checkedstr, *fp_result;//FILE *name = fopen(filename,type);
        fp_strpool = fopen(argv[1], "r");fp_checkedstr = fopen(argv[2], "r");fp_result = fopen(argv[3], "w");


2)如何获取系统当前时间(可以看自己的程序运行了多久)
ps:这段代码是我在网上搜到的

#include <time.h>int main (){time_t rawtime;struct tm * timeinfo1;time (&rawtime);timeinfo1 = localtime(&rawtime);printf("current time :%s",asctime(timeinfo1));.......your code........struct tm * timeinfo2;time (&rawtime);timeinfo2 = localtime(&rawtime);printf("current time is :%s",asctime(timeinfo2));}


3)从文件中读取字符串:fgets

fgets 可以从文件中读取字符串char *fgets(char *buf, int bufsize, FILE *stream) 从stream中读取bufsize个字符,第1024个为\0,读取的字符串保存在buf中


4)写入文件fprintf

eg:fprintf(filepointer, "%d, no\n",a);  


5)哈希函数是干嘛的:

跟数据结构课本中学到的有点不一样,我原来觉得哈希函数就是给一个数算出来一个存储位置

现在接触的哈希函数是 把不定长度的字符串变成一个unsigned int型的数







我的全部代码:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include "GeneralHashFunctions.h"#define HASH_NUM 11#define BIT_ARRAY_LENGTH 239620000void bf_add(void *,char *);int bf_search(void *,char *);unsigned int (*hashfamily[HASH_NUM])(char *,unsigned int)={&RSHash, &JSHash, &PJWHash, &ELFHash, &BKDRHash, &SDBMHash, &DJBHash, &DEKHash, &BPHash, &FNVHash, &APHash};void bf_check(FILE *strpool,FILE *checkemail,FILE *result);int main (int argc, char *argv[]){FILE * strpool,* checkedemial,*result;char line[1024];//open emailpool  r means read,w means writestrpool = fopen(argv[1],"r");checkedemial = fopen(argv[2],"r");result = fopen(argv[3],"w");bf_check(strpool,checkedemial,result);return 0;}void bf_check(FILE *strpool,FILE *checkedemail,FILE *result){void *bf;//初始化bfbf =  malloc(BIT_ARRAY_LENGTH);//blommfilter createdchar line1[1024];char line2[1024];    while (fgets(line1,1024,strpool) ){bf_add(bf,line1);}int position=0;while(fgets(line2,1024,checkedemail)){bf_search(bf,line2);position++;//record the checkedemail lineif(bf_search(bf,line2)==1){fprintf(result,"%d,yes\n",position);}if(bf_search(bf,line2)==0){fprintf(result,"%d,no\n",position);}}}//bf_checkvoid bf_add(void *bf,char *line){int i=0;while(i<HASH_NUM){unsigned int bit=hashfamily[i](line,strlen(line));int k=bit/8%BIT_ARRAY_LENGTH;int j=bit%8;char *c=(char) *bf;c[k]=(0x00000001<<j)|c[k];i++;}}//bf_addint bf_search(void *bf,char *line){int i=0;while(i<HASH_NUM){unsigned int bit=hashfamily[i](line,strlen(line));int k=bit/8%BIT_ARRAY_LENGTH;int j=bit%8;char *c=(char) *bf;if((int)(c[k]&(0x00000001<<j))==0) return 0;else return 1;i++;}}//bf_search

另外:GeneralHashFunctions.h  和GeneralHashFunctions.c是网上下载的

网址:http://www.partow.net/programming/hashfunctions/


补充一下:关于置位函数和检查标志位函数

为了节约内存,我们把bf转换为char型,一个char型数组是一个字节,8位。相当于把bf划分成8位的一个个的小储存空间。i=bit/8%BIT_ARRAY_LENGTH可以算出来是哪个小空间,然后再j=bit%8,得到小空间里对应的位,然后把0000 0001左移j位,与原来小空间的位们或运算,这样不会影响原来已经计算出来是0还是1的位。

    在检察标志位的时候,用整个小空间的数和左移位后的0000 0001相与,比如左移4位,是0110 0001 0001 0000相与,结果是0000 0000,转换成int型之后是0,所以可以判定原来那个位是一个0,而不是1,也不影响其他位,这样就返回0;如果是0111 00010001 0000相与,得到0001 0000,转换成int型之后不是0,可以判定原来是1,返回1



0 0