哈希表.docx
《哈希表.docx》由会员分享,可在线阅读,更多相关《哈希表.docx(9页珍藏版)》请在冰豆网上搜索。
哈希表
#include
#include
#include
#include
#defineN32//关键字个数
#definesize256
#definemaxlen9//关键字数组长度
#definehashlen41//哈希表长度
structhashtable//结构体数组哈希表
{
char*hash1;//指向关键字的指针
intcount;//记录频度
}hasht[hashlen];
usingnamespacestd;
voidHashfunc(charstr[]);//将关键字根据哈希函数放入哈希表中的指定位置
intHashfind(char*words);//在哈希表中找是否该words为关键字,并统计频度
voidcreathash(void);//创建哈希表
intisletter(charch);//判断是否为字母
intreadc(char*filename);//读取源程序文件中的单词
intgetkey(char*str,intlen);//获取该单词的key
voidresethash(intn);//重置哈希表
voidcopycount(intx[],intn);//将频道拷贝到数组里
voidcheck(int*x1,int*x2);//计算相对距离
intmain()
{
charfilename1[]={"test1.txt"};
charfilename2[]={"test12.txt"};
intx1[hashlen],x2[hashlen];//存储频度的数组,用于相似度S的计算
resethash(0);//完全重置哈希表,即哈希指针置为NULL,频度置为0
creathash();//通过文件ckey.txt创建哈希表
readc(filename1);//读取第一个测试源程序文件
copycount(x1,hashlen);//讲统计好的频度复制给x数组
resethash
(1);//仅仅将频度count置为0
readc(filename2);//同上
copycount(x2,hashlen);
resethash
(1);
cout<<"\t"<<"哈希序号"<<"\t"<<"关键字"<<"\t"<<"频度1"<<"\t"<<"频度2"<<"\t"<for(inti=0;i<41;i++)
{
if(hasht[i].hash1!
=NULL)
{
cout<<"\t"<
}
}
cout<"<check(x1,x2);//检查相似度
return0;
}
voidresethash(intn)
{//重置哈希表
if(n=0)//完全重置哈希表
{
for(inti=0;i<41;i++)
{
hasht[i].hash1=NULL;
hasht[i].count=0;
}
}
elseif(n=1)//仅仅重置频度
{
for(inti=0;i<41;i++)
{
hasht[i].count=0;
}
}
}
voidcopycount(intx[],intn)
{//拷贝频度
for(inti=0;i{
x[i]=hasht[i].count;
}
}
intgetkey(char*str,intlen)//根据哈希函数获取该单词的key
{
charkey1,key2;
intkey;
key1=str[0];
key2=str[len-1];
key=(int)(key1*100+key2)%41;
returnkey;
}
voidcreathash(void)//对文件ckey.txt中的32个关键字创建哈希表
{
FILE*fp;
intlength;
charstr[size];//暂时存储关键字字符的数组
char*s=NULL;
for(inti=0;i{
str[i]='\0';
}
if((fp=fopen("ckey.txt","r"))==NULL)
{
cout<<"can'tcreatfile!
\n";
exit(0);
}
while(fgets(str,size,fp)!
=NULL)//读取一行写入一行
{
if(str==NULL)
{
break;
}
length=strlen(str);
str[length-1]='\0';//调试后发现的,没有这里就停止运行了
Hashfunc(str);
}
fclose(fp);
}
voidHashfunc(charstr[])
{//将关键字根据哈希函数放入哈希表中的指定位置
intkey,len;
len=strlen(str);
key=getkey(str,len);
while(hasht[key%41].hash1!
=NULL)
{
key++;//线性探索
}
hasht[key%41].hash1=(char*)malloc(sizeof(char)*(len+1));
strcpy(hasht[key%41].hash1,str);
}
intHashfind(char*words)//在哈希表中找是否该words为关键字,并统计频度
{
intkey,len,find;
len=strlen(words);
key=getkey(words,len);
while(hasht[key].hash1==NULL)key++;
key=key%41;
if(strcmp(hasht[key].hash1,words)==0)
{
hasht[key].count++;
return1;
}
for(find=key+1;find{
//线性探查法顺序查找哈希表中是否已存在关键字
if(hasht[find].hash1!
=NULL)
{
if(strcmp(hasht[find].hash1,words)==0)
{
hasht[find].count++;
return1;
}
}
}
for(find=0;find{
if(hasht[find].hash1!
=NULL)
{
if(strcmp(hasht[find].hash1,words)==0)
{
hasht[find].count++;
return1;
}
}
}
return0;
}
intisletter(charch)
{//判断是否ch为字母
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))return1;
return0;
}
intreadc(char*filename)
{//读取源程序文件中的单词
FILE*fp1=NULL;
charwords[maxlen],ch;
inti;
if((fp1=fopen(filename,"r"))==NULL)
{
cout<<"cannotcreatfile!
\n";
exit(0);
}
while(!
feof(fp1))//结束返回1
{
i=0;
ch=fgetc(fp1);//一个字符一个字符的读
while(isletter(ch)==0&&feof(fp1)==0)
{
ch=fgetc(fp1);
}
while(isletter(ch)==1&&feof(fp1)==0)
{
if(i==maxlen)
{
while(isletter(ch)==1&&feof(fp1)==0)
{
ch=fgetc(fp1);
}
i=0;
break;
}//超过最大关键字长度将会跳过当前识别区域,读取下一个单词
else
{
words[i++]=ch;
ch=fgetc(fp1);
}
}
words[i]='\0';
Hashfind(words);//将得到的该单词调入Hashfind函数,来判断是否为关键字,并统计频度
}
fclose(fp1);
return0;
}
floatMol(int*x)//取模函数
{
inti=0,sum=0;
for(i=0;i{
sum+=(x[i]*x[i]);
}
return(float)pow((float)sum,0.5);
}
intDot(int*x1,int*x2)
{//点积函数
inti=0,sum=0;
for(i=0;i{
sum+=x1[i]*x2[i];
}
returnsum;
}
floatS(int*x1,int*x2)
{
returnDot(x1,x2)/(Mol(x1)*Mol(x2));//求相似度S
}
floatD(int*x1,int*x2)//求几何距离
{
intx[N],i=0;
for(i=0;i{
x[i]=x1[i]-x2[i];
}
returnMol(x);//再求模
}
voidcheck(int*x1,int*x2)
{
inta;
floatb;
inti,sum=0;
for(i=0;i{
a=x1[i]-x2[i];
sum+=a*a;
}
b=sqrt(sum);
cout<<"相似度="<
return;
}