#####################
Hash.h
typedef struct Hash{
char key[100];
int sd;
int cont;
}Hs;
######################
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "Hash.h"
//第一个文件
int Check1(int a[])
{
Hs hatb[30];//哈希表的长度
FILE *ky;
FILE *fp;
int adr=0;
int len=0,i=0,j=0,n=0;
int g=13;//关键字的数量
char s[50];
char str[15][15];
fp=fopen("D:\\1.txt","r+");
ky=fopen("D:\\3.txt","r+");
//***关键字文件 导入 二维数组
for(i=0;i<g;i++)
{
a[i]=0;
}
i=0;
while(!feof(ky))
{
fscanf(ky,"%s",str[i]);
//*************************//
//***********猜测范围板块**************//
//***因为要考虑到哈希表的长度、关键字的数量***********//
len=0;//得到每个串的长度所以要置零
len=strlen(str[i]);
len=(str[i][0]+str[i][(len-1)/2]+1+len);//构造哈希函数:开头第一个和中间一个之和除以三
adr=len%9;//在这里我是用9 作为一个素数,来求模取余
printf("关键字的地址值:%d ",adr);
//******在设计过程中逐渐增加关键字的数量,要不然运行时间太长了*****************//
puts(str[i]);
i++;
}
//板块一:哈希表的初始化
for(i=0;i<30;i++)
{
strcpy(hatb[i].key,"NULLKEY");
hatb[i].sd=0;
hatb[i].cont=0;
}
printf("\n");
//printf("11111\n");板块一结束
// ###################***********************************########################
板块二:检查程序中的代码
while(!feof(fp))
{
fscanf(fp,"%s",s);
for(i=0;i<g;i++)
{
if(strcmp(s,str[i])==0)//是否匹配
{
j++;
//********板块二结束
//板块三:
//当 找到 关键字后将其放入哈希表 更新哈希表的 关键字,试探次数,值
//****************生成哈希表*******************
//
//
int f=1;//作为标记
len=0;//得到每个串的长度所以要置零
len=strlen(s);
len=(s[0]+s[(len-1)/2]+len+1);//构造哈希函数
adr=len%9;//在这里我是用9 作为一个素数求模
//printf("aa");
if(strcmp(hatb[adr].key,"NULLKEY")==0)
{
strcpy(hatb[adr].key,s);
hatb[adr].sd=1;//试探的次数
hatb[adr].cont=1;//关键字第一次出现;
}
else
{
if(strcmp(hatb[adr].key,s)==0)
{
hatb[adr].cont++;
}
else
{
while(strcmp(hatb[adr].key,"NULLKEY")!=0)
{
adr=(adr+1)%9;//新址
if(strcmp(hatb[adr].key,s)==0)
{
hatb[adr].cont++;
f=0;
break;
}
}
if(f==1)
{
strcpy(hatb[adr].key,s);
hatb[adr].cont++;
}
}
}
a[i]=hatb[adr].cont;
printf("%d,%d ",i,a[i]);
//第一次是没被占用所以 数量和次数 变成一else不执行;
//而如果位置被占用 第一个if是不执行的,执行else,被占用分两种情况:一种是和这个被占用的匹配
//执行if 将数目加一 但是 试探次数不变,否则要线性试探,找新地址一直到新地址可用,这个过程中
//如果新地址的关键字和程序匹配,那么该地址下的次数就加一,直接break退出;在不是已经匹配的关键字的前提下
//他还会继续找新地址直到找到为止。
//板块三结束*************************
memset(s,'0',sizeof(s));
break;
}
}
}
printf("\n");
// #####################***********************************#######################
//板块四:这里能看出来确实是正确的,但是我不敢使用太长的程序 和 太多的关键字来测试
//输出 未被 占用的哈希表
for(i=0;i<30;i++)
{
if(strcmp(hatb[i].key,"NULLKEY")!=0)
{
puts(hatb[i].key);
printf("位置:%d,试探:%d,次数:%d\n",i,hatb[i].sd,hatb[i].cont);
}
}
//板块四结束
printf("文件一共%d处匹配\n",j);
fclose(fp);//关闭文件
fclose(ky);
printf(" 打印分界线 \n");
for(i=0;i<1;i++)
{
for(j=0;j<60;j++)
{
printf("*");
}
printf("\n");
for(j=0;j<60;j++)
{
printf("#");
}
printf("\n");
}
system("pause");
return 0;
}
//第二个文件///^^^^^^^^^^^^^^^^^^^^^********************#############**********************
int Check2(int b[])
{
Hs hatb[30];//哈希表的长度
FILE *ky;
FILE *fp;
int adr=0;
int len=0,i=0,j=0,n=0;
int g=13;//关键字的数量
char s[50];
char str[15][15];
fp=fopen("D:\\2.txt","r+");
ky=fopen("D:\\3.txt","r+");
//***关键字文件 导入 二维数组
for(i=0;i<g;i++)
{
b[i]=0;
}
i=0;
while(!feof(ky))
{
fscanf(ky,"%s",str[i]);
//*************************//
//***********猜测范围板块**************//
//***因为要考虑到哈希表的长度、关键字的数量***********//
len=0;//得到每个串的长度所以要置零
len=strlen(str[i]);
len=(str[i][0]+str[i][(len-1)/2]+1+len);//构造哈希函数:开头第一个和中间一个之和除以三
adr=len%9;//在这里我是用9 作为一个素数,来求模取余
printf("关键字的地址值:%d ",adr);
//******在设计过程中逐渐增加关键字的数量,要不然运行时间太长了*****************//
puts(str[i]);
i++;
}
//板块一:哈希表的初始化
for(i=0;i<30;i++)
{
strcpy(hatb[i].key,"NULLKEY");
hatb[i].sd=0;
hatb[i].cont=0;
}
printf("\n");
//printf("11111\n");板块一结束
// ###################***********************************########################
板块二:检查程序中的代码
while(!feof(fp))
{
fscanf(fp,"%s",s);
for(i=0;i<g;i++)
{
if(strcmp(s,str[i])==0)//是否匹配
{
j++;
//********板块二结束
//板块三:
//当 找到 关键字后将其放入哈希表 更新哈希表的 关键字,试探次数,值
//****************生成哈希表*******************
//
//
int f=1;//作为标记
len=0;//得到每个串的长度所以要置零
len=strlen(s);
len=(s[0]+s[(len-1)/2]+len+1);//构造哈希函数
adr=len%9;//在这里我是用9 作为一个素数求模
//printf("aa");
if(strcmp(hatb[adr].key,"NULLKEY")==0)
{
strcpy(hatb[adr].key,s);
hatb[adr].sd=1;//试探的次数
hatb[adr].cont=1;//关键字第一次出现;
}
else
{
if(strcmp(hatb[adr].key,s)==0)
{
hatb[adr].cont++;
}
else
{
while(strcmp(hatb[adr].key,"NULLKEY")!=0)
{
adr=(adr+1)%9;//新址
if(strcmp(hatb[adr].key,s)==0)
{
hatb[adr].cont++;
f=0;
break;
}
}
if(f==1)
{
strcpy(hatb[adr].key,s);
hatb[adr].cont++;
}
}
}
b[i]=hatb[adr].cont;
//第一次是没被占用所以 数量和次数 变成一else不执行;
//而如果位置被占用 第一个if是不执行的,执行else,被占用分两种情况:一种是和这个被占用的匹配
//执行if 将数目加一 但是 试探次数不变,否则要线性试探,找新地址一直到新地址可用,这个过程中
//如果新地址的关键字和程序匹配,那么该地址下的次数就加一,直接break退出;在不是已经匹配的关键字的前提下
//他还会继续找新地址直到找到为止。
//板块三结束*************************
memset(s,'0',sizeof(s));
break;
}
}
}
// #####################***********************************#######################
//板块四:这里能看出来确实是正确的,但是我不敢使用太长的程序 和 太多的关键字来测试
//输出 未被 占用的哈希表
int k=0;
for(i=0;i<30;i++)
{
if(strcmp(hatb[i].key,"NULLKEY")!=0)
{
puts(hatb[i].key);
printf("位置:%d,试探:%d,次数:%d\n",i,hatb[i].sd,hatb[i].cont);
}
}
//板块四结束
printf("文件一共%d处匹配\n",j);
fclose(fp);//关闭文件
fclose(ky);
return 0;
}
int main()
{
FILE *ky;
int i=0,j=0;
int g=13;//关键字个数
int k1=0,k2=0,len=0;
int a[13];
int b[13];
char str[30][30];
Check1(a);
Check2(b);
ky=fopen("D:\\3.txt","r+");
while(!feof(ky))
{
fscanf(ky,"%s",str[i]);
len=strlen(str[i]);
printf("%7s",str[i]);
printf(" ");
}
printf("\n");
printf("程序一:\n");
for(i=0;i<g;i++)
{
printf("%7d ",a[i]);
}
printf("\n");
printf("程序二:\n");
for(i=0;i<g;i++)
{
printf("%7d ",b[i]);
}printf("\n");
double sum=0.0;
double t=0;
for(i=0;i<g;i++)
{
t=(a[i]-b[i])*(a[i]-b[i]);
sum=t+sum;
}
sum=sqrt(sum);
printf("程序相似性:%lf",sum);
return 0;
}
期末小作业
使用哈希表来看代码相似性 使用了线性试探来解决冲突