哈希实验报告Word格式文档下载.docx

上传人:b****6 文档编号:20064483 上传时间:2023-01-16 格式:DOCX 页数:21 大小:137.91KB
下载 相关 举报
哈希实验报告Word格式文档下载.docx_第1页
第1页 / 共21页
哈希实验报告Word格式文档下载.docx_第2页
第2页 / 共21页
哈希实验报告Word格式文档下载.docx_第3页
第3页 / 共21页
哈希实验报告Word格式文档下载.docx_第4页
第4页 / 共21页
哈希实验报告Word格式文档下载.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

哈希实验报告Word格式文档下载.docx

《哈希实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《哈希实验报告Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。

哈希实验报告Word格式文档下载.docx

X2=(4205405201)T

一般情况下,可以通过计算向量Xi和Xj的相似值来判断对应两个程序的相似性,相似值的判别函数计算公式为:

其中,

S(Xi,Xj)的值介于[0,1]之间,也称广义余弦,即S(Xi,Xj)=COSθ。

Xi=Xj时,显见S(Xi,Xj)=1,θ=0;

XiXj差别很大时,S(Xi,Xj)接近0,θ接近π/2。

如X1=(10)T,X2=(01)T,则S(Xi,Xj)=0,θ=π/2。

当S值接近1的时候,为避免误判相似性(可能是夹角很小,模值很大的向量),应当再次计算之间的“几何距离”D(Xi,Xk)。

其计算公式为:

最后的相似性判别计算可分两步完成:

第一步用式(3-1)计算S,把接近1的保留,抛弃接近0的情况(把不相似的排除);

第二步对保留下来的特征向量,再用式(3-2)计算D,如D值也比较小,说明两者对应的程序确实可能相似(慎重肯定相似的)。

S和D的值达到什么门限才能决定取舍?

需要积累经验,选择合适的阈值。

3)测试数据:

做几个编译和运行都无误的C程序,程序之间有相近的和差别大的,用上述方

法求S,并对比差异程度。

二、需求分析

1.本程序能够打印根据关键字建立的哈希表及利用该表统计的C语言源程序关键字使用情况,得出源程序的相似性。

2.将关键字输入key.txt中,关键字均为char型,以空格分开,将要比较的源程序存入不同文本文档中,运行时按提示输入源程序个数和相应的文档名称,若输入多个源程序,比较时输入相应的源程序序号(序号为输入源程序的顺序)。

3.输出建立的哈希表,按哈希表统计的源程序关键字使用情况,所比较的两个程序间的相似度以及向量的几何距离。

三、概要设计

为了实现上述功能,需要哈希表抽象数据类型。

哈希表抽象数据类型定义:

ADTHashList{

数据对象:

D是相同类型元素构成的结合。

数据关系:

R={集合内的元素之间是松散关系}

基本操作:

intDimension(LinkHashListHT);

//求哈希表元素总个数

intHashFunc(char*e);

//哈希函数

voidInitHashList(LinkHashList&

HT,intm,FILE*fp);

//创建哈希表

voidInsertHT(LinkHashList&

HT,char*e);

//插入元素

LNode*SearchHT(LinkHashListHT,char*e);

//查找元素

voidHashBuild(FILE*fp,LinkHashList&

HT);

//统计源程序每个关键字频度

voidHashclear(LinkHashList&

HT,intm);

//将哈希表每个关键字频度置零

voidTraverseHT(LinkHashListHT);

//输出哈希表

}ADTHashList

5.本程序保护模块:

主程序模块

哈希表单元模块:

实现哈希表抽象数据类型

调用关系:

主程序模块->

哈希表单元模块

四、详细设计

1.结点类型和结点指针类型:

typedefstructLNode{

chardata[10];

intaccount;

structLNode*next;

}LNode,**ppLNode;

typedefstruct{

ppLNodehead;

intlength;

}LinkHashList;

2.哈希表的实现

求哈希表元素总个数

intDimension(LinkHashListHT)

{

intd,count=0;

LNode*p;

for(d=0;

d<

43;

d++)

{

p=HT.head[d];

while(p){p=p->

next;

count++;

}

}

returncount;

哈希函数

intHashFunc(char*e)

inti;

for(i=0;

i<

10;

i++)

if(e[i]=='

\0'

)break;

return((e[0]*100+e[i-1])%41);

HT,char*e)

intd=HashFunc(e);

LNode*p=newLNode;

strcpy(p->

data,e);

p->

account=0;

next=HT.head[d];

HT.head[d]=p;

LNode*SearchHT(LinkHashListHT,char*e)

LNode*p=HT.head[d];

while(p&

&

strcmp(p->

data,e)!

=0)p=p->

returnp;

//创建哈希表

HT,intm,FILE*fp)

{inti,d;

charstr[10];

HT.head=newLNode*[m];

HT.length=m;

m;

HT.head[i]=NULL;

LNode*p=newLNode;

strcpy(p->

data,"

\0"

);

p->

next=HT.head[i];

HT.head[i]=p;

charch=fgetc(fp);

while(ch!

=EOF)

if(ch=='

'

ch!

=EOF)

do

{ch=fgetc(fp);

}while(ch=='

i=0;

='

{

str[i++]=ch;

ch=fgetc(fp);

}

str[i]='

;

InsertHT(HT,str);

统计源程序每个关键字频度

HT)

inti,d;

while((ch<

97||ch>

122)&

i=0;

if(ch>

96&

ch<

123)

while(ch>

{

}

LNode*p=SearchHT(HT,str);

if(p)p->

account++;

ch=fgetc(fp);

将哈希表每个关键字频度置零

HT,intm)

{LNode*p;

{p=HT.head[i];

while(p)

{p->

p=p->

//遍历哈希表

voidTraverseHT(LinkHashListHT)

p=HT.head[0]->

cout<

<

"

["

0<

]"

while(p->

next){

data<

->

account;

endl;

for(inti=1;

HT.length;

i++){

p=HT.head[i];

}//for

3.函数调用关系图

五、调试分析

1.hashbuild函数中,在文件中搜索字符时,采用的方法是比较ASC码的值,但是总是执行后无法继续,后来发现是ch在最后被赋值为EOF而没有经外层循环的判断跳出,因而在内层循环中也添加了一个判断。

2.原先利用哈希表对源程序关键字计数时,没有考虑在统计完一个程序后,要对哈希表计数的量重新置零,得到的结果总是不对,后来添加了hashclear函数,得到了正确的结果。

3.输出统计结果时,注意到哈希表的插入是对head前插,所以每个单元最后一个节点没有赋关键字符值,还是初始值零,输出时跳过,但是后面将统计结果赋值给数组时,这些值也赋值进去了,因为全部是零,所以不影响后面的相似度判断,只是增加了向量的维度而已。

4.最后比较相似度是,取S值为0.9,D值为10。

若有更合理的阈值,要对它们进行修正。

5.复杂度分析

函数时间复杂度空间复杂度

DimensionO(n+d)O

(1)

InitHashListO(n+d)O(n+d)

HashBuildO(n+d)O

(1)

HashclearO(n+d)O

(1)

CosineO(n+d)O

(1)

DistanceO(n+d)O

(1)

六、使用说明

程序运行后根据提示输入所要进行的操作,输入关键字存储文件名,源程序存储文件名。

程序将打印建立的哈希表,对源程序的统计结果,相似度和几何距离。

七、调试结果

使用joseph,parking两个源程序用上述方法求S,D,并对比差异程度。

建立的哈希表

 

joseph.txt源程序:

intMinEdge(floatlow[],intVexnum)

inti,j,m,flag=0;

floatk;

for(i=0;

Vexnum;

for(j=0;

j<

j++)

if(low[i]==0&

low[j]!

=0)

k=low[j];

m=j;

flag=1;

break;

}

if(flag)break;

=0&

k>

low[j])

returnm;

统计结果

parking.txt源程序

inti01,j,k;

i=1000;

floatlowcost[MAX_VEX_NUM];

ArcNode*p;

G.VexNum-1;

{p=G.vertices[v0].firstarc;

while(p)

j=p->

adjvex;

lowcost[j]=p->

weight;

adjvex[j]=v0;

nextarc;

if(!

VexJudge(G,v0,i))lowcost[i]=1000;

比较结果

八、附录

源代码

Hash.h

doubleCosine(int(*w)[76],inta,intb,intm);

doubleDistance(int(*w)[76],inta,intb,intm);

Hash.cpp

#include<

stdio.h>

stdlib.h>

iostream.h>

#include<

string.h>

math.h>

#include"

hash.h"

intDimension(LinkHashListHT)//求哈希表中元素总个数

HT,char*e)//插入元素

LNode*SearchHT(LinkHashListHT,char*e)//查找元素

HT,intm,FILE*fp)//创建哈希表

//从文件中读取关键字

HT)//对文件中关键字进行统计

HT,intm)//统计量置零

doubleCosine(int(*w)[76],inta,intb,intm)//计算S

inti,s=0,v=0,u=0;

doublecos=0;

s=s+(*(*(w+a)+i))*(*(*(w+b)+i));

u=u+(*(*(w+a)+i))*(*(*(w+a)+i));

v=v+(*(*(w+b)+i))*(*(*(w+b)+i));

cos=s/(sqrt(v)*sqrt(u));

returncos;

doubleDistance(int(*w)[76],inta,intb,intm)//计算D

inti,s=0;

s=s+(*(*(w+a)+i)-*(*(w+b)+i))*(*(*(w+a)+i)-*(*(w+b)+i));

returnsqrt(s);

voidTraverseHT(LinkHashListHT)//遍历哈希表

程序相似性比较.cpp

voidmain()

intn,i,j,p,q,dim,k=0;

doubles,d;

charkey[20],source[20],choice;

intweight[10][76];

FILE*fp,*fp1;

LinkHashListHHT;

LNode*node;

cout<

请输入关键字存储文件名:

cin>

>

key;

if((fp=fopen(key,"

r"

))==NULL)

printf("

cantopenfile"

exit

(1);

InitHashList(HHT,43,fp);

TraverseHT(HHT);

请输入源程序个数:

n;

cout<

请输入源程序存储文件名:

cin>

source;

if((fp1=fopen(source,"

cantopenthefile"

}

HashBuild(fp1,HHT);

dim=Dimension(HHT);

printf("

用哈希表统计结果为:

\n"

for(j=0;

dim&

k<

)//把统计结果赋值给数组,构造向量

{node=HHT.head[k++];

while(node)

weight[i][j]=node->

node=node->

j++;

k=0;

Hashclear(HHT,43);

是否比较(Y\N):

choice;

while(choice=='

Y'

cout<

请输入源程序序号(按照输入顺序):

//编号i,向量在数组中存储与第i行

p>

q;

s=Cosine(weight,p-1,q-1,dim);

相似度S="

s;

if(s>

0.9)

d=Distance(weight,p-1,q-1,dim);

cout<

几何距离D="

d;

if(d<

10)cout<

两个程序相似\n"

elsecout<

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1