这次老师留的作业是海量字符串查找
很多同学用了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");
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));
}
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 239620000
void 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 write
strpool = 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;//初始化bf
bf = malloc(BIT_ARRAY_LENGTH);//blommfilter created
char 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 line
if( bf_search(bf,line2)==1){fprintf(result,"%d,yes\n",position);}
if( bf_search(bf,line2)==0){fprintf(result,"%d,no\n",position);}
}
}//bf_check
void 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_add
int 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 0001与0001 0000相与,得到0001 0000,转换成int型之后不是0,可以判定原来是1,返回1。