《课程设计报告利用哈希技术统计C源程序关键字出现频度.doc》由会员分享,可在线阅读,更多相关《课程设计报告利用哈希技术统计C源程序关键字出现频度.doc(16页珍藏版)》请在三一办公上搜索。
1、 数据结构与算法课程设计报告 题目:利用哈希技术统计C源程序关键字出现频度 学生姓名: 学 号: _ 班 级: _ 指导教师: _ 2012年 6 月 18 日利用哈希技术统计C源程序关键字出现频度(1)题目内容:利用Hash技术统计某个C源程序中的关键字出现的频度(2)基本要求:扫描一个C源程序,用Hash表存储该程序中出现的关键字,并统计该程序中的关键字出现的频度。用线性探测法解决Hash冲突。设Hash函数为:Hash(key)(key的第一个字母序号)*100+(key的最后一个字母序号) MOD 41 一、对题目的分析哈希表是为了便于快速搜索而组织的值组合的集合。Hash Table
2、是一种数组,可以用任意简单变量值来访问其元素,这种数组叫做关联数组,也叫哈希表。值对的集合。理想的情况下是希望不经过任何比较,一次存储就能得到所查到的记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的存储位置相对应。基本要求:使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数,也叫做散列函数),使得每个元素的关键字都与一个函数值(即数组下标,hash值)存在一一对应的关系,于是用这个数组单元来存储这个元素。使用hash表存储关键字时难免会有不同的关键字对应同一关键码的情况,因此必须有个处理冲突的办法。Hash函数:Hash(k
3、ey)(key的第一个字母序号)*100+(key的最后一个字母序号) MOD 41 二、处理冲突的方法处理冲突的办法线性探测法用线性探法解决冲突时,把有冲突的关键字往后推移直到有空位置的关键码时再插入到hash表中。C语言关键字: C语言关键字是C语言的保留的一些单词,这些单词都有了固定的意义和用途,不可以作为变量或者自定义类型或类名来使用。其特点是都有小写字母构成。C语言关键字有哪些:double int structbreakelselongswitch caseenumregistercharextern returnunionconstfloatshortunsignedcontin
4、uefor signedvoiddefaultgotosizeofvolatiledowhilestaticifautocase定义一个多维数组,数组第一行存放关键字,数组第二行存储hash函数处理后关键字结点地址,用hash函数存储关键字Hash(Key)=(Key第一个字符在1-26个字母中的序号)*100+(Key最后一个字符在1-26个字母中的序号)%41如此得到如for对应地址3,if对应于地址4,int对应地址18等等。哈希表 H(key)=keyMOD41 处理冲突为线性探测再散列。 三、算法设计及部分函数打开含关键字的CPP文件:int Open(char *filename)
5、char wordMaxLength,ch;int i;FILE *read; /指向FILE类的指针*read if(read=fopen(filename,r)=NULL) /只读方式读取文件,如果为空coutendl未找到要打开的文件,请重新输入!;return -1; /跳出Open函数while(!feof(read) /判断文件是否结束,到末尾函数值为“真”即非0i=0;ch=fgetc(read); /读取一个字符while(LetterNot(ch)=0&feof(read)=0)ch=fgetc(read); /如果不是字母就接着读取,关键字都是由字母组成的while(Let
6、terNot(ch)=1&feof(read)=0)if(i=MaxLength)while(LetterNot(ch)=1&feof(read)=0)ch=fgetc(read); /超过MAXLEN的长度则一定不为关键字,把余下连一起的字母都读取i=0;break;elsewordi+=ch; /把读取到的字母存入word数组中ch=fgetc(read);wordi=0;if(KeywordsNot(word)CreatHash(word);fclose(read);coutendl文件中关键字已经存入表中,请继续!endlendlendl;在Hash表中查找关键字找出关键字位置:int
7、 FindHash(char *keyword) /在Hash表中查找关键字int key,find,FindColl=0;if(!KeywordsNot(keyword) /是否关键字return -1;key=GetHashValue(keyword);if(strcmp(Testkey.keyword,keyword)=0)return key;for(find=key+1;findLengthofHash;find+) /线性探测法FindColl+; /FindColl统计冲突次数if(strcmp(Testfind.keyword,keyword)=0)Testfind.coll=
8、FindColl; /把冲突次数存入collreturn find;for(find=0;find0) /Hash表中该位置存在关键字 if(strcmp(Testkey.keyword,keyword)=0) /Hash表中该位置的关键字相同 Testkey.count+; /频度加1return 1; /跳出函数key=FindHash(keyword); /不相同,继续查找if(key0) /没有找到相等的keywordkey=Insert(GetHashValue(keyword);if(key0) /Hash表满或者计算的Hash值有问题return -1;strcpy(Testke
9、y.keyword,keyword); /将关键字插入Hash表if(key0)return -1;Testkey.count+;else /该位置没有关键字strcpy(Testkey.keyword,keyword);Testkey.count+;return 1;在Hash表中插入关键字:int Insert(int key) /在Hash表中插入关键字int find,FindColl=0;if(key=LengthofHash) return -1;for(find=key+1;findLengthofHash;find+) /分块查找后部分FindColl+;if(strlen(T
10、estfind.keyword)=0) /若这个地方为空 Testfind.coll=FindColl; /把冲突的次数存入coll中 return find; for(find=0;findkey;find+) /分块在前部分查找FindColl+;if(strlen(Testfind.keyword)=0)Testfind.coll=FindColl;return find;return -1; /Hash表已满四、算法的实现a)引用库函数定义变量#include #include #include #include using namespace std;const int Length
11、ofHash=41; /Hash表长度int keycount=0; /统计Hash表中的关键字总数const int Total=38; /38个关键字const int MaxLength=20; char KeyWordsTotalMaxLength= /列举38个关键字bool,break,case,catch,char,class,const,continue,default,do,double,else,enum,extern,false,float,for,goto,if,int,interrupt,long,new,private,public,register,return,
12、short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,while,;b)类的构造及类的对象class ConuntNum public:int coll; /collision冲突次数int count; /出现次数(频度)char keywordMaxLength; ConuntNum TestLengthofHash;c)函数的声明部分void Menu();void PrintScreen(int key);int Open(char *filename); int LetterNot(char ch);
13、int KeywordsNot(char *word);int FindHash(char *keyword);int CreatHash(char *keyword);int Insert(int key);int GetHashValue(char *keyword);d)在Hash表中分块查找int FindHash(char *keyword) /在Hash表中查找关键字int key,find,FindColl=0;if(!KeywordsNot(keyword) /是否关键字return -1;五、源代码#include #include #include #include usi
14、ng namespace std;const int LengthofHash=41; /Hash表长度int keycount=0; /统计Hash表中的关键字总数const int Total=38; /38个关键字const int MaxLength=20; char KeyWordsTotalMaxLength= /列举38个关键字bool,break,case,catch,char,class,const,continue,default,do,double,else,enum,extern,false,float,for,goto,if,int,interrupt,long,ne
15、w,private,public,register,return,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,while,;class ConuntNum public:int coll; /collision冲突次数int count; /出现次数(频度)char keywordMaxLength; ConuntNum TestLengthofHash;/先声明后使用void Menu();void PrintScreen(int key);int Open(char *filename); int
16、 LetterNot(char ch);int KeywordsNot(char *word);int FindHash(char *keyword);int CreatHash(char *keyword);int Insert(int key);int GetHashValue(char *keyword);void main() char opt; int option=1,i,count,key,has;char filename50,wordMaxLength; while(option) Menu(); cinopt;switch(opt) case 1:system(cls);
17、coutfilename;Open(filename); coutendl; continue;break; case 2: system(cls);cout按回车键继续显示!endl;for(i=0;iLengthofHash;i+) PrintScreen(i); if(i+1)%10=0)getchar(); /10行一循环 coutCPP文件中关键字总数为:keycountendl;coutendlendlendlendlendl;continue; system(cls); break;case 3:system(cls); cout冲突关键字列表:endlendl; count=0
18、; for(i=0;i0) key=GetHashValue(Testi.keyword); if(key!=i) count+; coutt关键字Testi.keyword; couttHash表当前位置:i; coutt冲突次数:Testi.collendl; if(count=0) cout没有冲突endlendlendlendlendl; else coutendlttt冲突关键字共:count个endl;coutendlendlendlendlendl;continue; system(cls); break; case 4:system(cls);cout输入你想要查找的关键字:
19、word; coutendl; PrintScreen(FindHash(word);coutendl;continue; system(cls); break; case 5:option=0;break;default: system(cls);int Open(char *filename)char wordMaxLength,ch;int i;FILE *read; /指向FILE类的指针*read if(read=fopen(filename,r)=NULL) /只读方式读取文件,如果为空coutendl未找到要打开的文件,请重新输入!;return -1; /跳出Open函数whi
20、le(!feof(read) /判断文件是否结束,到末尾函数值为“真”即非0i=0;ch=fgetc(read); /读取一个字符while(LetterNot(ch)=0&feof(read)=0)ch=fgetc(read); /如果不是字母就接着读取,关键字都是由字母组成的while(LetterNot(ch)=1&feof(read)=0)if(i=MaxLength)while(LetterNot(ch)=1&feof(read)=0)ch=fgetc(read); /超过MAXLEN的长度则一定不为关键字,把余下连一起的字母都读取i=0;break;elsewordi+=ch; /
21、把读取到的字母存入word数组中ch=fgetc(read);wordi=0;if(KeywordsNot(word)CreatHash(word);fclose(read);coutendl文件中关键字已经存入表中,请继续!endlendl=a&ch=A&ch=Z)return 1; elsereturn 0; int FindHash(char *keyword) /在Hash表中查找关键字int key,find,FindColl=0;if(!KeywordsNot(keyword) /是否关键字return -1;key=GetHashValue(keyword);if(strcmp(
22、Testkey.keyword,keyword)=0)return key;for(find=key+1;findLengthofHash;find+) /线性探测法FindColl+; /FindColl统计冲突次数if(strcmp(Testfind.keyword,keyword)=0)Testfind.coll=FindColl; /把冲突次数存入collreturn find;for(find=0;find0) /Hash表中该位置存在关键字 if(strcmp(Testkey.keyword,keyword)=0) /Hash表中该位置的关键字相同 Testkey.count+;
23、/频度加1return 1; /跳出函数key=FindHash(keyword); /不相同,继续查找if(key0) /没有找到相等的keywordkey=Insert(GetHashValue(keyword);if(key0) /Hash表满或者计算的Hash值有问题return -1;strcpy(Testkey.keyword,keyword); /将关键字插入Hash表if(key0)return -1;Testkey.count+;else /该位置没有关键字strcpy(Testkey.keyword,keyword);Testkey.count+;return 1;int
24、Insert(int key) /在Hash表中插入关键字int find,FindColl=0;if(key=LengthofHash) return -1;for(find=key+1;findLengthofHash;find+) /分块查找后部分FindColl+;if(strlen(Testfind.keyword)=0) /若这个地方为空 Testfind.coll=FindColl; /把冲突的次数存入coll中 return find; for(find=0;findkey;find+) /分块在前部分查找FindColl+;if(strlen(Testfind.keyword
25、)=0)Testfind.coll=FindColl;return find;return -1; /Hash表已满int KeywordsNot(char *word) /判断是否关键字int i;for(i=0;iTotal;i+)if(strcmp(word,KeyWordsi)=0)return 1;return 0;void PrintScreen(int key) if(key=LengthofHash)cout关键字不存在!endl;return;if(strlen(Testkey.keyword)=0)coutHash表位置: key 记录是空的!endl;return;cou
26、tHash表位置: keyt关键字: Testkey.keywordtt出现次数:Testkey.countendl;keycount+;int GetHashValue(char *keyword) int HashValue; HashValue=(keyword0*100+keywordstrlen(keyword)-1)%41;return HashValue;void Menu() couttt*endl; couttt* 1.读取CPP文件 *endl; couttt* 2.输出Hash表中的关键字 *endl; couttt* 3.显示冲突的关键字 *endl; couttt*
27、4.在Hash表中查找关键字 *endl; couttt* 5.退出 *endl;couttt* 请选择(1-5): *endl; couttt*endl;六、程序运行结果截图图1 程序运行界面图2 载入含关键字的CPP图3 输出Hash表中的关键字图4 显示冲突的关键字图5 查找关键字在Hash表中的位置七、课程设计心得体会这次课程设计让我了解到自己在Hash表这一块有着许多的不足,在各方面都缺乏最重要的知识。通过这次课程设计,我了解到自己在实践操作方面还有很多不足,在实践过程中老师和同学给了我很大的帮助和鼓励,学会了团结精神的重要性,以及做事必须一丝不苟,遇到困难不能半途而废要有不惧困难探求真理,踏踏实实的解决问题。参考文献:李根强 编著,数据结构(C+版) (第二版), 中国水利水电出版社