利用哈希技术统计C源程序关键字出现频度

合集下载

哈希表统计次数

哈希表统计次数

哈希表统计次数哈希表是一种常用的数据结构,用于统计元素的出现次数。

它通过将元素映射到一个固定的位置来实现快速的插入和查找操作。

在本文中,我们将探讨哈希表统计次数的原理、应用场景以及一些相关的算法。

一、哈希表统计次数的原理哈希表是由一个数组和一个哈希函数组成的。

哈希函数将元素映射到数组的某个位置上,并将元素存储在该位置上。

当需要统计元素的次数时,只需要通过哈希函数找到元素所在的位置,并将该位置上的计数器加一即可。

哈希表统计次数广泛应用于各种领域,例如文本处理、数据分析、网络流量分析等。

在文本处理中,可以使用哈希表统计单词的出现次数,从而得到文本的词频分布。

在数据分析中,可以使用哈希表统计用户的行为次数,从而了解用户的使用习惯。

在网络流量分析中,可以使用哈希表统计IP地址的访问次数,从而发现异常访问行为。

三、哈希表统计次数的算法1. 链地址法链地址法是最常见的解决哈希冲突的方法之一。

它将哈希表的每个位置都设置为一个链表,当发生哈希冲突时,将冲突的元素插入到链表的末尾。

这样,可以保证每个位置上的元素都能被找到,并且插入和查找的时间复杂度为O(1)。

2. 开放地址法开放地址法是另一种解决哈希冲突的方法。

它通过线性探测、二次探测、双重哈希等方式来寻找下一个可用的位置。

当发生哈希冲突时,会依次探测下一个位置,直到找到一个空闲的位置或者遍历完整个哈希表。

这样,可以保证每个元素都能被插入到哈希表中,并且插入和查找的时间复杂度为O(1)。

四、哈希表统计次数的优化1. 负载因子负载因子是指哈希表中已经存储的元素个数与哈希表长度的比值。

当负载因子过大时,哈希冲突的概率会增大,从而影响插入和查找的性能。

因此,可以通过调整负载因子来优化哈希表的性能。

2. 哈希函数哈希函数的选择对哈希表的性能有着重要影响。

一个好的哈希函数应该能够将元素均匀地映射到不同的位置上,从而减少哈希冲突的概率。

常见的哈希函数有除法取余法、乘法取整法、平方取中法等。

哈希实验报告

哈希实验报告

一、 问题描述1. 实验题目:利用哈希表统计两源程序的相似性2. 基本要求:1)内容: 对于两个 C 语言的源程序清单,用哈希表的方法分别统计两程序中使用C 语言关键字的情况,并最终按定量的计算结果,得出两份源程序的相似性。

2)要求与提示:C 语言关键字的哈希表可以自建,也可以采用下面的哈希函数作为参考: Hash(key)=(key 第一个字符序号*100+key 最后一个字符序号)%41表长m 取43。

此题的工作主要是扫描给定的源程序,累计在每个源程序中C 语言关键字出现的频度。

为保证查找效率,建议自建哈希表的平均查找长度不大于2。

扫描两个源程序所统计的所有关键字不同频度, 可以得到两个向量。

如下面简单的例子所示:根据程序1和程序2中关键字出现的频度,可提取到两个程序的特征向量X1和X2,其中 X1=(4 3 0 4 3 0 7 0 0 2)TX2=(4 2 0 5 4 0 5 2 0 1)T一般情况下,可以通过计算向量Xi 和Xj 的相似值来判断对应两个程序的相似性,相似值的判别函数计算公式为: ji Ti j i X X X X X S ⋅=)(,其中,i T i X X X ⋅=。

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

X i =X j 时,显见S(X i ,X j )=1,θ=0;X i X j 差别很大时,S(X i ,X j )接近0,θ接近π/2。

如X1=(1 0)T,X2=(0 1)T,则S(X i ,X j )=0,θ=π/2。

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

其计算公式为:)()(),(k i Tk i k i j i X X X X X X X X D --=-= 最后的相似性判别计算可分两步完成:第一步 用式(3-1)计算S ,把接近 1的保留,抛弃接近0的情况(把不相似的排除); 第二步 对保留下来的特征向量,再用式(3-2)计算D ,如D 值也比较小,说明两者对应的程序确实可能相似(慎重肯定相似的)。

2022年三峡大学计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)

2022年三峡大学计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)

2022年三峡大学计算机科学与技术专业《数据结构与算法》科目期末试卷A(有答案)一、选择题1、若需在O(nlog2n)的时间内完成对数组的排序,且要求排序是稳定的,则可选择的排序方法是()。

A.快速排序B.堆排序C.归并排序D.直接插入排序2、n个结点的完全有向图含有边的数目()。

A.n*nB.n(n+1)C.n/2D.n*(n-1)3、若线性表最常用的操作是存取第i个元素及其前驱和后继元素的值,为节省时间应采用的存储方式()。

A.单链表B.双向链表C.单循环链表D.顺序表4、下面关于串的叙述中,不正确的是()。

A.串是字符的有限序列B.空串是由空格构成的串C.模式匹配是串的一种重要运算D.串既可以采用顺序存储,也可以采用链式存储5、已知串S='aaab',其next数组值为()。

A.0123B.1123C.1231D.12116、已知字符串S为“abaabaabacacaabaabcc”,模式串t为“abaabc”,采用KMP算法进行匹配,第一次出现“失配”(s!=t)时,i=j=5,则下次开始匹配时,i和j的值分别()。

A.i=1,j=0 B.i=5,j=0 C.i=5,j=2 D.i=6,j=27、下列选项中,不能构成折半查找中关键字比较序列的是()。

A.500,200,450,180 B.500,450,200,180C.180,500,200,450 D.180,200,500,4508、在下述结论中,正确的有()。

①只有一个结点的二叉树的度为0。

②二叉树的度为2。

③二叉树的左右子树可任意交换。

④深度为K的完全二叉树的结点个数小于或等于深度相同的满二叉树。

A.①②③B.⑦③④C.②④D.①④9、一棵非空的二叉树的前序序列和后序序列正好相反,则该二叉树一定满足()。

A.其中任意一个结点均无左孩子B.其中任意一个结点均无右孩子C.其中只有一个叶结点D.其中度为2的结点最多为一个10、分别以下列序列构造二叉排序树,与用其他三个序列所构造的结果不同的是()。

哈希表之词频统计

哈希表之词频统计

哈希表之词频统计#include <stdio.h>typedef struct node_t{struct node_t *next;char *word;int count;}*node;#define NHASH 9973 // 最好定位质数#define MULT 31 // 乘法器node bin[NHASH]; // 哈希表索引unsigned int hash(char *p){unsigned int h = 0;for(; *p; p++)h = MULT * h + *p;return h % NHASH;}void incword(char *s){unsigned int h = hash(s);node p;for(p=bin[h]; p; p=p->next)if(strcmp(s, p->word) == 0){(p->count)++;return;}p = malloc(sizeof(*p));p->count = 1;p->word = malloc(strlen(s)+1);strcpy(p->word, s);p->next = bin[h]; // 栈式插⼊,从表头处插⼊,⽽⾮从表的尾部插⼊bin[h] = p;}void main(int argc, char **argv){int i;char buf[32];for(i=0; i<NHASH; i++)bin[i] = NULL;int ii = 0, cc;while(1){scanf("%s",buf);printf("--- %d\n", ii++);if(*buf == 'q')break;incword(buf);}node p;for(i=0; i<NHASH; i++)for(p = bin[i]; p; p = p->next)printf("%s:%d\n", p->word, p->count);}以哈希表为数据结构统计词频⼤致思路:构造⼀个结构体数组 struct node_t bin[质数]; 称为哈希表构造⼀个哈希函数,给定⼀个字符串返回⼀个整数,这个整数哈希表的键值;每获取⼀个字符串,把字符串与它的所对应键值的node 节点为表头的链表上的所有单词⽐较,若存在相同的,count++,否则增加到链表节点,把单词挂到该节点上,并置count=1;输出的时候,从哈希表的0键值处开始,遍历所有链表,并输出各⾮空节点;。

百度笔试题及答案解析-百度笔试题及答案解析

百度笔试题及答案解析-百度笔试题及答案解析

百度笔试题及答案-百度笔试题及答案百度java笔试题(含答案)更多面试题,百度面试笔试题解答答案专家回答:第一题简评百度的主要业务是搜索,搜索的基本原理如下1.编写爬虫程序到互联网上抓取网页海量的网页。

2.将抓取来的网页通过抽取,以一定的格式保存在能快速检索的文件系统中。

3.把用户输入的字符串进行拆分成关键字去文件系统中查询并返回结果。

由以上3点可见,字符串的分析,抽取在搜索引擎中的地位是何等重要。

因此,百度的笔试面试题中,出现这样的题就变得理所当然了。

以下是该题的java实现,代码如下:程序代码程序代码import *;import *;import *;/** * @author tzy * 在下测试通过*/public class FileNameStat{private String srcPath;//要统计的文件路径private Map statMap;//用于统计的mappublic FileNameStat(String srcPath){=srcPath; 软件开发网statMap=new TreeMap();}/*获得要统计的URL的文件名*/public String getFileName(String urlString){URL url=null;String filePath=null;String fileName=null;try{url=new URL(urlString);filePath=();int index=0;if ((index=(“/”))!=-1){fileName=(index+1);else{fileName=““;}}catch(MalformedURLException e){}return fileName;}/*统计指定文件名的个数*/public void stat(String filename){Integer count=null;if((filename)!=null){count=(Integer)(filename); count=new Integer(()+1); }else{count=new Integer(1);}(filename,count);}/*统计的主方法*/public void start() throws FileNotFoundException,IOException {BufferedReader bfin=new BufferedReader(new FileReader());String temp=null;while((temp=())!=null){stat(getFileName(temp));}}/*输出统计结果*/public void result(){Iterator it=().iterator();while(()){entry=()(());((().equals(““)?”空文件名”:()) + “的个数是”+ ()); }}public static void main(String args) throws Exception{FileNameStat fns=new FileNameStat(““);//指定成待统计文件();();}}第二题简评:这道题也与百度的业务有关,百度现在除了搜索外,还有贴吧,知道,博客等重要产品。

c语言hash用法

c语言hash用法

c语言hash用法一、概述Hash是一种常用的数据结构,用于将任意长度的数据映射到固定长度的数据中。

在C语言中,可以使用hash来实现数据的快速查找和插入操作。

Hash算法的原理是将数据通过一系列函数映射到一个固定长度的哈希值,从而实现对数据的快速查找和插入。

二、hash的实现方式在C语言中,常用的hash实现方式有线性探测和平方探测等。

线性探测是指在查找失败时,顺序地检查已存在的哈希链中的下一个元素,直到找到空位或者遍历完整个哈希链。

平方探测是指当哈希值碰撞时,检查该碰撞点后面的位置,如果没有冲突则直接插入,否则进行链式存储。

三、hash的使用步骤1. 定义哈希表结构体和哈希函数首先需要定义哈希表结构体,包括存储数据的数组和哈希函数等。

哈希函数的作用是将输入的数据映射到哈希表中存储的位置。

常用的哈希函数有直接平方取余法、除法取余法等。

2. 初始化哈希表在使用hash之前,需要将哈希表进行初始化,即创建一个空的数组并分配相应的内存空间。

3. 插入数据将需要插入的数据通过哈希函数映射到哈希表中存储的位置,并将数据存储在该位置。

如果该位置已经存在数据,则需要根据具体的哈希算法进行处理,例如进行链式存储等。

4. 查找数据根据需要查找的数据通过哈希函数映射到哈希表中存储的位置,并检查该位置是否存储了需要查找的数据。

如果找到了需要查找的数据,则返回该数据的指针;否则返回空指针。

5. 删除数据根据需要删除的数据通过哈希函数映射到哈希表中存储的位置,并执行相应的删除操作。

四、hash的优缺点Hash的优点包括:1. 插入和查找速度快:由于哈希表使用的是数组结构,因此可以在O(1)时间内完成插入和查找操作。

2. 空间利用率高:哈希表使用链式存储时,可以有效地利用空间,避免出现数据重叠的情况。

然而,Hash也存在一些缺点:1. 冲突概率:由于哈希函数的不确定性,可能会出现数据碰撞的情况。

如果碰撞过多,则需要使用链式存储等方法进行处理。

数据结构与算法课程设计计划书-2011-2012-2(10级).

数据结构与算法课程设计计划书-2011-2012-2(10级).

计算机科学与工程学院集中性实践教学计划书( 2011-2012 学年第二学期课程名称:数据结构与算法课程设计专业:计算机科学与技术软件工程、网络工程班级:计算机科学与技术101-6软件工程101-4网络工程101-4课程负责人:李锡祚、王玲芬、李威指导教师分配情况:专业指导教师计算机科学与技术李威、李笑牛、张恒博、云健、刘爽、包书哲软件工程王玲芬、王鹏杰、王存睿、孙世昶、网络工程李锡祚、姜楠、王晓强、王波教学起止周:第1 至3 教学周一、教学目的与要求:数据结构与算法课程设计的目的是使同学们能够根据数据对象的特性,合理的组织数据并能综合运用数据结构与算法基本知识和程序设计基本知识解决实际问题,培养基本的、良好的程序设计技能。

二、主要阶段、内容、时间及地点安排(以天为单位计:阶段与内容第1阶段:指导教师布置设计任务并解析有关题目的设计指标和任务的具体内容,学生选择题目,明确问题描述和要求,查阅资料。

(1天;各班长或学习委员将本班的选题表交给辅导教师,一人一题,每道题的选择人数原则上不能超过3人,第一天课程设计结束后,每名学生都要确定题目。

第2阶段:明确题目要求、确定数据结构、设计算法,编写程序、调试程序、测试程序(11天;第一周,学生应明确题目要求、确定数据的逻辑结构和存储结构、实现基本操作的编码与调试、实现主菜单。

第二周,完成核心算法的设计、编码与调试。

第三周,完成剩余任务的编码与调试,准备足够的测试数据,对软件进行测试与调试。

第3阶段:完成设计任务,准备验收、答辩(1天;第4阶段:答辩(上机演示,回答教师提问(1天;第5阶段:撰写课程设计报告(2天。

地点与时间地点:金石滩校区图书馆时间:计算机科学与技术:课程设计上机时间表周一周二周三周四周五第一周上午、下午上午第2大节、下午第二周上午、下午上午第2大节、下午第三周上午、下午上午第2大节、下午(验收软件工程:课程设计上机时间表周一周二周三周四周五第一周上午、下午上午、下午下午第二周上午、下午上午、下午下午第三周上午、下午上午、下午下午(验收网络工程:课程设计上机时间表周一周二周三周四周五第一周上午、下午上午下午上午第二周上午、下午上午下午上午第三周上午、下午上午下午上午(验收注:上午8:30~11:10下午1:40~4:20三、课程设计题目及具体要求:1.成绩管理问题描述:给出n个学生的考试成绩表,成绩表包括学生的学号、姓名、考试成绩(高等数学、英语、物理,设计一个简单的成绩管理程序。

c语言 hash查找算法

c语言 hash查找算法

c语言 hash查找算法Hash查找算法(Hash Search Algorithm)是一种通过哈希函数将键映射到特定位置的查找算法。

哈希查找算法的核心思想是将关键字通过哈希函数转化为数组的索引,从而实现快速的查找和存储。

一、哈希函数的作用哈希函数是哈希查找算法的核心组成部分,它将关键字映射到数组的特定位置。

哈希函数的设计需要满足以下两个条件:1. 确定性:对于相同的输入,哈希函数应该返回相同的输出;2. 均匀性:哈希函数应该尽量将关键字均匀地分布到数组的不同位置。

二、哈希表的实现哈希表是哈希查找算法的基础数据结构,它由一个固定大小的数组和一个哈希函数组成。

数组的每个位置称为一个槽位(Slot),每个槽位可以存储一个关键字。

当插入或查找一个关键字时,通过哈希函数将关键字映射到数组的特定位置,实现快速的插入和查找操作。

三、哈希冲突的处理由于哈希函数的映射是有限的,不同的关键字可能映射到数组的同一个位置,这就导致了哈希冲突(Hash Collision)的问题。

哈希冲突会使得不同的关键字存储在同一个槽位中,因此需要一种策略来解决冲突。

常见的解决冲突的方法有以下几种:1. 链地址法(Chaining):将冲突的关键字存储在同一个槽位中的一个链表中;2. 开放地址法(Open Addressing):当发生冲突时,通过探测序列的方法找到下一个可用的槽位;3. 再哈希法(Rehashing):当发生冲突时,通过应用另一个哈希函数来寻找下一个可用的槽位。

四、哈希查找的优势和应用场景相比于其他的查找算法,哈希查找算法具有以下几个优势:1. 时间复杂度较低:在理想情况下,哈希查找的时间复杂度为O(1);2. 适用于大规模数据:哈希查找算法适用于大规模数据的查找和存储;3. 支持高效的插入和删除操作:哈希查找算法可以在常数时间内完成插入和删除操作。

哈希查找算法常被应用于以下场景:1. 数据库索引:哈希查找算法可以用于数据库查询的索引结构,提高查询效率;2. 缓存系统:哈希查找算法可以用于缓存系统中的数据存储和查找,提高缓存的访问速度;3. 路由表查找:哈希查找算法可以用于路由器中的路由表查找,快速定位目标地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

:利用哈希技术统计C源程序关键字出现频度目录一.需求分析说明 (3)二.总体设计 (3)三.详细设计 (4)四.实现部分 (5)五.程序测试 (10)六.总结 (11)一、需求分析说明1.课程设计目的本课程设计的目的就是要达到理论与实际应用相结合,使同学们能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养基本的、良好的程序设计技能。

2.题目要求1)题目内容:利用Hash技术统计某个C源程序中的关键字出现的频度2)基本要求:扫描一个C源程序,用Hash表存储该程序中出现的关键字,并统计该程序中的关键字出现的频度。

用线性探测法解决Hash冲突。

设Hash函数为:Hash(key)[(key的第一个字母序号)*100+(key的最后一个字母序号)] MOD 41二、总体设计一.算法思想描述首先读取关键字文件以建立二叉排序树以供后续查询,每个树节点保存一个关键字字符串及指向左右子树的指针。

同时创建一Hash表,每个节点除应保存关键字字符串外,还应保存关键字频数及该存储单元冲突次数。

然后扫描一个C源程序,每次扫描一行,从中循环分离出每个单词,每次均查找其是否为关键字,若是,则按计算公式计算其KEY值并在Hash表中进行相应操作,若该节点为空则插入否者比较其是否与现有关键字相同,若相同则增加其频数,否则增加其冲突次数并继续线性探测下一个存储单元,完了继续操作下一个分离出来的单词,如此循环运行直至扫描结束。

编写本程序时,使用了二叉树创建、二叉树查找、Hash表的建立和操作及文件操作等基本算法。

二.三、详细设计三.(程序结构//Hash表存储结构typedef struct node //定义{ char s[20];int num,time; //num为频数,time为冲突次数}node;//二叉排序树结构定义typedef struct nod //定义{ char s[20];struct nod *left,*right;}nod;int max;//max为Hash表长度函数说明:nod *creat():读关键字文件,按照关键字中字符字母先后顺序建立二叉排序树,每个节点中保存一个关键字;void init(node *head):初始化Hash表各节点数据域;void deal(node *head,nod *parent,char filename[]):扫描源文件,分离出每个单词,检验是否为关键字;并根据检验结果来决定是否调用strdeal函数,以对Hash做适当更改;void strcp(node *head,char s[],int k):将新查找到的关键字复制到Hash表中第k个节点存储单元;void strdeal(node *head,char s[],int k):判断Hash表中第k个单元中有无关键字,若无则将当前关键字存入该单元,返回;否则比较两关键字是否相等,相等则将该单元频数加一,返回;不相等则将该单元冲突数加一并循环线性探测下一个存储单元;int strcmp(char t[],char s[]):字符串比较;void prin(nod *head):以左根右的顺序将二叉排序树打印在屏幕上;四、实现部分#include <iostream.h>#include <string>#include <iomanip.h>using namespace std;const int TOTAL=39; //39个关键字const int MAXLEN=10; //关键字长度const int HASHLEN=41; //哈希表长度int cont=0; //统计哈希表中的关键字个数void jiemian();void Show(int key);void Select(int choice);int Read(char *filename);int Input();int isLetter(char ch);int isKeyWords(char *word);int FindHX(char *keyword);int CreatHX(char *keyword);int GetFreePos(int key);void ResetHX();int GetKey(char *keyword);char KeyWords[TOTAL][MAXLEN]= //构造二维数组存储39个关键字{"asm","auto","break","case","cdecl","char","const","continue","default","do","double","else","enum","extern","far","float","for","goto","huge","if","int","interrupt","long","near","pascal","register","return","short","signed","sizeof","static","struct","switch","typedef","union","unsigned","void","volatile","while",};/******************************************************************** ***typedef struct HASH{char keyword[MAXLEN];int count; //出现次数(频度)int con; //冲突次数}HASH HS[HASHLEN];/******************************************************************** ********/class HASH //哈希表类{public:char keyword[MAXLEN];int count; //出现次数(频度)int con; //冲突次数};HASH HS[HASHLEN];int main(){ResetHX(); //先清空哈希表cout<<"\t=================================================== =============="<<endl;cout<<"\t* 欢迎使用该软件,请按提示操作*"<<endl;cout<<"\t* 该程序功能是统计一个文件中C语言关键字的频度*"<<endl;cout<<"\t* 统计开始前请先读取一个文件*"<<endl;cout<<"\t**"<<endl;cout<<"\t* by 黄耀广*"<<endl;cout<<"\t=================================================== =============="<<endl<<endl;jiemian();Select(Input());return(0);}void jiemian()//主菜单函数{cout<<endl;cout<<"\t\t1.读取一个文件"<<endl;cout<<"\t\t2.输出Hash表(关键字总数,冲突次数)"<<endl;cout<<"\t\t3.查询某关键字在Hash表中的情况"<<endl;cout<<"\t\t4.显示Hash表中的冲突关键字"<<endl;cout<<"\t\t5.显示C语言关键字的Hash函数值(作为对照)"<<endl;cout<<"\t\t6.回主菜单"<<endl;cout<<"\t\t7.退出"<<endl;}int Input(){cout<<endl;cout<<"按'6'回主菜单,请输入你的选择(1-7): ";while(true) //确保输入的为数字{int choice=0;if((cin>>choice)){if((choice<=0)||(choice>7))cout<<"输入范围不正确,请重新输入"<<endl;}else{cout<<"输入错误,请重新输入"<<endl;cin.clear();}while(!isspace(cin.get())) //功能:判断字符是否为空白符//说明:当字符为空白符时,返回非零值,否则返回零。

//空白符指空格、水平制表、垂直制表、换页、回车和换行符。

continue;cout<<endl;return choice;}}void Show(int key)//显示出某关键字的频度{if(key<0||key>=HASHLEN){cout<<"关键字不存在!"<<endl;return;}if(strlen(HS[key].keyword)==0){cout<<"哈希表位置:"<<key<<" 记录是空的"<<endl;return ;}cout<<"哈希表位置: "<<key<<" 关键字: "<<HS[key].keyword<<" 出现次数"<<HS[key].count<<endl;cont++;}void Select(int choice){char filename[128],word[MAXLEN];int i,key,count;switch(choice){case 1:cout<<"请输入要读取的文件名(文件必须与程序在同一目录下):";cin>>filename;cout<<endl;Read(filename);//read函数从一个文件读字节到一个指定的存储器区域,由长度参数确定要读的字节数Select(Input());break;case 2:cout<<"每次显示5行,请按回车键继续!"<<endl<<endl;for(i=0;i<HASHLEN;i++){Show(i);if((i+1)%5==0) getchar(); //为了清晰,每次显示5行}cout<<"关键字总数为:"<<cont<<endl;Select(Input());break;case 3:cout<<"请输入你想要查找的关键字:";cin>>word;cout<<endl;Show(FindHX(word));Select(Input());break;case 4:cout<<"\t冲突关键字列表"<<endl<<endl;count=0;for(i=0;i<HASHLEN;i++){if(strlen(HS[i].keyword)>0){key=GetKey(HS[i].keyword);if(key!=i){count++;cout<<"\t[关键字]: "<<HS[i].keyword<<endl;cout<<"\t[哈希表当前位置]: "<<i<<endl;cout<<"\t[冲突次数]: "<<HS[i].con<<endl<<endl;}}}if(count==0)cout<<"没有冲突"<<endl;elsecout<<"\t冲突关键字共:"<<count<<"个"<<endl;Select(Input());break;case 5:cout<<" C语言中的关键字和其在哈希表的位置:"<<endl;for(i=0;i<TOTAL;i++){cout<<setiosflags(ios::left)<<"["<<setw(2)<<GetKey(KeyWords[i])<<"]"<<setiosflags(ios::left)<<setw(11)<<KeyWords[i];if((i+1)%5==0) cout<<endl;}cout<<endl;Select(Input());break;case 6:jiemian();Select(Input());case 7:break;//退出default:Select(Input());return;}}int Read(char *filename) //读取文件{char word[MAXLEN],ch;int i;FILE *read;if( (read=fopen(filename,"r"))==NULL ) //只读方式打开一个文本文件,只允许读数据{cout<<"文件不存在,请确认好再输入!"<<endl;return -1;}ResetHX(); //读取文件前先清空哈希表while(!feof(read)) //feof()是文件结束检测函数,如果没有结束,返回值是0,结束了是1{i=0;ch=fgetc(read); //读取一个字符while(isLetter(ch)==0 && feof(read)==0 ) ch=fgetc(read);//如果不是字母的话接着读取while(isLetter(ch)==1 && feof(read)==0 ){if(i==MAXLEN){while(isLetter(ch)==1&& feof(read)==0){ch=fgetc(read);}i=0;break;}//超过关键字长度将跳过当前识别区域,读取后一单词else{ //将连续读取的字母存在数组里,组成一个单词word[i++]=ch;ch=fgetc(read);}}word[i]='\0'; //字符数组的结束标志if(isKeyWords(word)){CreatHX(word);}}fclose(read);cout<<"读取成功,文件中关键字已经存入hash表,请继续操作"<<endl;jiemian();return 1;}int isLetter(char ch) //判断是否是字母,因为关键字都是英文单词{if( (ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z') ) return 1;else return 0;//是字母就返回1,否则返回0值}int FindHX(char *keyword) //查找哈希表,分块查找{int key,find,tem=0;if(!isKeyWords(keyword)) return -1;key=GetKey(keyword);if(strcmp(HS[key].keyword,keyword)==0) return key;for(find=key+1;find<HASHLEN;find++){ //线性探查法顺序查找哈希表中是否已存在关键字tem++; //统计冲突次数if(strcmp(HS[find].keyword,keyword)==0){HS[find].con=tem;return find; }}for(find=0;find<key;find++){tem++;if(strcmp(HS[find].keyword,keyword)==0){HS[find].con=tem;return find; }}return -1;}int CreatHX(char *keyword) //建立哈希表{int key;if(!isKeyWords(keyword)) return -1;key=GetKey(keyword); //计算哈希值if(strlen(HS[key].keyword)>0) //判断关键字表中该位置是否存在关键字{ //已经存在有关键字if(strcmp(HS[key].keyword,keyword)==0){ //再判断哈希表中该位置的关键字是否相同HS[key].count++;return 1;}key=FindHX(keyword); //不相同,继续查找if(key<0){key=GetFreePos(GetKey(keyword));if(key<0) return -1;strcpy(HS[key].keyword,keyword); //将关键字插入哈希表}if(key<0) return -1;HS[key].count++;}else //该位置为空,直接将关键字插入该位置中{strcpy(HS[key].keyword,keyword);HS[key].count++;}return 1;}int GetFreePos(int key) //在哈希表中给关键字找个位置插进去{int find,tem=0;if(key<0||key>=HASHLEN) return -1;for(find=key+1;find<HASHLEN;find++) //先找后面的位置{tem++;if(strlen(HS[find].keyword)==0){HS[find].con=tem;return find; }}for(find=0;find<key;find++) //再找前面的位置{tem++;if(strlen(HS[find].keyword)==0){HS[find].con=tem;return find; }}return -1; //哈希表已满}void ResetHX() //重置哈希表,{int i;for(i=0;i<HASHLEN;i++){strcpy(HS[i].keyword,""); //不能用等号赋值HS[i].count=0;HS[i].con=0;}}int GetKey(char *keyword) //哈西函数{ //Hash函数为:Hash(Key)=[(Key的首字母序号)*100+(Key的尾字母序号)] Mod 41return ( keyword[0]*100+keyword[strlen(keyword)-1] ) % 41; //这里不要忘了减1}int isKeyWords(char *word) //判断是否关键字{int i;for(i=0;i<TOTAL;i++)if(strcmp(word,KeyWords[i])==0) return 1;return 0;}五.程序测试:文件一:HASH序号关键字频数冲突数3 return 8 04 long 3 05 typedef 1 06 goto 2 07 if 38 010 do 1 013 void 15 014 case 10 015 default 1 019 sizeof 1 021 int 29 122 switch 1 024 else 16 027 char 13 228 unsigned 2 033 struct 4 034 break 10 0总关键字数:164总冲突数:3文件二:HASH序号关键字频数冲突数0 while 11 03 return 130 04 long 26 06 goto 1 07 if 194 010 do 14 013 void 1 014 case 12 015 default 5 016 static 37 019 sizeof 12 021 interrupt 9 7022 int 69 123 for 75 224 else 68 225 far 1 126 switch 1 027 char 73 128 unsigned 1 034 break 20 2435 struct 22 236 short 2 0总关键字数:789总冲突数:127由以上数据可知,扫描不同的源文件,在模相同的情况下,其关键字经扫描后在Hash 表中存储的各项数据次序基本相同;并且,由程序运行结果可知Hash表空间开辟越大其冲突次数也并非一定减少。

相关文档
最新文档