利用哈希技术统计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(有答案)一、选择题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用法一、概述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 学年第二学期课程名称:数据结构与算法课程设计专业:计算机科学与技术软件工程、网络工程班级:计算机科学与技术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查找算法Hash查找算法(Hash Search Algorithm)是一种通过哈希函数将键映射到特定位置的查找算法。
哈希查找算法的核心思想是将关键字通过哈希函数转化为数组的索引,从而实现快速的查找和存储。
一、哈希函数的作用哈希函数是哈希查找算法的核心组成部分,它将关键字映射到数组的特定位置。
哈希函数的设计需要满足以下两个条件:1. 确定性:对于相同的输入,哈希函数应该返回相同的输出;2. 均匀性:哈希函数应该尽量将关键字均匀地分布到数组的不同位置。
二、哈希表的实现哈希表是哈希查找算法的基础数据结构,它由一个固定大小的数组和一个哈希函数组成。
数组的每个位置称为一个槽位(Slot),每个槽位可以存储一个关键字。
当插入或查找一个关键字时,通过哈希函数将关键字映射到数组的特定位置,实现快速的插入和查找操作。
三、哈希冲突的处理由于哈希函数的映射是有限的,不同的关键字可能映射到数组的同一个位置,这就导致了哈希冲突(Hash Collision)的问题。
哈希冲突会使得不同的关键字存储在同一个槽位中,因此需要一种策略来解决冲突。
常见的解决冲突的方法有以下几种:1. 链地址法(Chaining):将冲突的关键字存储在同一个槽位中的一个链表中;2. 开放地址法(Open Addressing):当发生冲突时,通过探测序列的方法找到下一个可用的槽位;3. 再哈希法(Rehashing):当发生冲突时,通过应用另一个哈希函数来寻找下一个可用的槽位。
四、哈希查找的优势和应用场景相比于其他的查找算法,哈希查找算法具有以下几个优势:1. 时间复杂度较低:在理想情况下,哈希查找的时间复杂度为O(1);2. 适用于大规模数据:哈希查找算法适用于大规模数据的查找和存储;3. 支持高效的插入和删除操作:哈希查找算法可以在常数时间内完成插入和删除操作。
哈希查找算法常被应用于以下场景:1. 数据库索引:哈希查找算法可以用于数据库查询的索引结构,提高查询效率;2. 缓存系统:哈希查找算法可以用于缓存系统中的数据存储和查找,提高缓存的访问速度;3. 路由表查找:哈希查找算法可以用于路由器中的路由表查找,快速定位目标地址。
人工智能机器学习技术练习(习题卷8)

人工智能机器学习技术练习(习题卷8)第1部分:单项选择题,共62题,每题只有一个正确答案,多选或少选均不得分。
1.[单选题]基于二次准则函数的H-K算法较之于感知器算法的优点是()?A)计算量小B)可以判别问题是否线性可分C)其解完全适用于非线性可分的情况答案:B解析:2.[单选题]构建回归树的时间复杂度最重要的因素是()A)特征中类别的个数B)label列值域C)样本总量答案:A解析:3.[单选题]()是指为最小化总体风险,只需在每个样本上选择能使特定条件风险最小的类别标记。
A)支持向量机B)间隔最大化C)线性分类器D)贝叶斯判定准则答案:D解析:4.[单选题]下列选择 Logistic回归中的 One-Vs-All方法中,()是真实的。
A)我们需要在n类分类问题中适合n个模型B)我们需要适合n-1个模型来分类为n个类C)我们需要只适合1个模型来分类为n个类D)以上答案都不正确答案:A解析:如果存在n个类,那么n个单独的逻辑回归必须与之相适应,其中每个类的概率由剩余类的概率之和确定。
5.[单选题](__)不属于相关分析。
A)正相关B)负相关C)线性相关D)误差相关答案:D解析:6.[单选题]移动运营商对客户进行细分,设计套餐和营销活动可以使用下面哪种机器学习方法( )。
A)贝叶斯分类器B)关联方法C)聚类算法D)多层前馈网络7.[单选题]下面是三个散点图(A,B,C,从左到右)和和手绘的逻辑回归决策边界。
alt="" >上图中哪一个显示了决策边界过度拟合训练数据?A)AB)BC)CD)这些都没有答案:C解析:由于在图3中,决策边界不平滑,表明其过度拟合数据。
8.[单选题]半监督学习包括。
A)主动学习B)回归学习C)聚类学习D)直推学习答案:D解析:9.[单选题]在统计语言模型中,通常以概率的形式描述任意语句的可能性,利用最大相似度估计进行度量,对于一些低频词,无论如何扩大训练数据,出现的频度仍然很低,下列哪种方法可以解决这一问题()A)一元切分B)一元文法C)数据平滑D)N元文法答案:C解析:10.[单选题]将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?A)频繁模式挖掘B)分类和预测C)数据预处理D)数据流挖掘答案:C11.[单选题]图像数据分析的常用方法不包括( )A)图像变换B)图像编码和压缩C)图像增强和复原D)图像数据采集答案:D解析:12.[单选题]下列关于数据的说法,不正确的是()A)数据的类别有多种多样B)数据库中的一列代表一个特征C)一组数据平均值不会受异常值影响D)数据点之间的距离满足d_ij+d_jk≥d_ik答案:C解析:13.[单选题]关于ZooKeeper的说法不正确是()A)采用层次化的数据结构B)采用类似于LINUX命令进行数据访问C)具备临时节点和永久节点D)永久节点会随客户端会话的结束而结束其生命周期答案:D解析:14.[单选题]下面数据结构能够支持随机的插入和删除操作、并具有较好的性能的是A)链表和哈希表B)数组和链表C)哈希表和队列D)堆栈和双向队列答案:A解析:15.[单选题]下面关于数据科学与统计学的关系描述不正确的有(__)。
哈希表统计次数

哈希表统计次数哈希表是一种常用的数据结构,它通过将数据与唯一的索引值关联起来,可以快速地查找、插入和删除数据。
在计算机科学中,哈希表被广泛应用于各种领域,如数据库管理系统、编译器、搜索引擎等。
本文将从不同的角度来探讨哈希表的统计次数。
一、哈希表的基本原理哈希表是由哈希函数和数组组成的。
哈希函数将数据映射到数组的特定位置,这个位置被称为索引值。
当需要查找、插入或删除数据时,只需要通过哈希函数计算出对应的索引值,就可以直接访问数组中的相应位置,从而实现高效的操作。
二、哈希表的统计次数在哈希表中,统计次数是指记录某个数据在哈希表中出现的次数。
通常,我们可以通过遍历哈希表来统计每个数据的出现次数。
具体的统计方法如下:1. 遍历哈希表,对每个数据进行计数。
2. 对于每个数据,如果它已经在哈希表中出现过,则将其对应的计数值加1;否则,将其加入哈希表,并将计数值初始化为1。
3. 最终,可以得到每个数据在哈希表中出现的次数。
三、哈希表的应用场景1. 字符串统计:哈希表可以用来统计字符串中每个字符出现的次数。
通过将每个字符映射到哈希表的索引值,然后计数,就可以得到字符串中每个字符的出现次数。
2. 单词统计:哈希表可以用来统计文本中每个单词出现的次数。
将文本分割成单词,然后将每个单词映射到哈希表的索引值,再计数,就可以得到文本中每个单词的出现次数。
3. 网络流量统计:哈希表可以用来统计网络流量中每个IP地址的出现次数。
将每个IP地址映射到哈希表的索引值,再计数,就可以得到每个IP地址的访问次数。
四、哈希表的优势和局限性哈希表具有以下优势:1. 高效的查找、插入和删除:通过哈希函数计算索引值,可以快速地定位数据。
2. 空间利用率高:哈希表可以根据实际数据量来动态调整数组的大小,从而节省内存空间。
3. 适用于大规模数据处理:哈希表可以处理大规模的数据,而不会因为数据量增加而导致性能下降。
然而,哈希表也存在一些局限性:1. 哈希冲突:不同的数据可能会映射到相同的索引值,从而导致冲突。
c语言调用哈希算法

在C语言中,可以使用哈希算法来生成固定长度的哈希值,用于快速比较、存储和检索数据。
常用的哈希算法有MD5、SHA-1、SHA-256等。
下面是一个简单的示例代码,演示如何使用C语言调用哈希算法。
```c#include <stdio.h>#include <string.h>#include <openssl/sha.h>int main() {char *str = "Hello, world!";unsigned char hash[SHA256_DIGEST_LENGTH];// 调用SHA-256哈希算法生成哈希值SHA256_CTX sha256;SHA256_Init(&sha256);SHA256_Update(&sha256, str, strlen(str));SHA256_Final(hash, &sha256);// 输出哈希值printf("Hash value: ");for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {printf("%02x", hash[i]);}printf("\n");return 0;}```在上面的代码中,我们使用了OpenSSL库中的SHA256哈希算法。
首先定义了一个字符串`str`,然后声明了一个长度为SHA256_DIGEST_LENGTH的哈希值数组`hash`,用于存储生成的哈希值。
接着,我们初始化了一个SHA256上下文`sha256`,并使用`SHA256_Update`函数将要哈希的数据传送给算法引擎进行哈希运算。
最后,使用`SHA256_Final`函数将哈希结果保存到`hash`数组中。
最后,我们使用`printf`函数输出生成的哈希值。
C语言hash用法

C语言hash用法在C语言中,哈希(Hash)通常用于将数据映射到一个固定大小的索引或键,以便快速检索数据,而不必遍历整个数据集。
C语言本身没有内置的哈希表(hash table)或哈希函数库,但你可以自己实现哈希表和哈希函数,或者使用第三方库来处理哈希操作。
以下是一些在C语言中使用哈希的基本用法:1. 实现哈希函数:首先,你需要编写一个哈希函数,将输入数据(通常是键)映射到一个索引或哈希值。
这个哈希函数应该尽可能均匀地分布数据,以减少哈希冲突的发生。
例如,一个简单的哈希函数可以是将字符串的每个字符的ASCII码相加,并对哈希表大小取模。
2. 创建哈希表:接下来,你需要创建一个哈希表数据结构,用于存储数据。
哈希表通常是一个数组,每个元素是一个指向数据的指针,如果有多个数据映射到同一个哈希值,可以使用链表或其他数据结构解决冲突。
3. 插入数据:将数据插入哈希表时,首先使用哈希函数计算出哈希值,然后将数据存储在对应的哈希表索引中。
如果发生冲突,可以使用链表等方法将数据添加到已存在的索引处。
4. 查找数据:要查找数据,使用哈希函数计算出哈希值,然后在哈希表中查找对应的索引。
如果有冲突,必须遍历冲突链表以找到所需的数据。
5. 删除数据:删除数据的过程与查找类似,首先计算哈希值,然后查找索引并删除数据。
需要小心处理冲突的情况。
请注意,上述是哈希表的基本用法。
在实际应用中,你可能需要处理更复杂的情况,例如动态调整哈希表大小、解决冲突的不同方法(如开放寻址法、链地址法等),以及处理碰撞时的性能优化等。
此外,如果你不想从头实现哈希表,也可以考虑使用第三方C语言库,如Glib中的哈希表功能,以简化哈希表的操作。
C语言中的哈希计算

C语言中的哈希计算哈希计算是计算机科学中一种常见的算法,用于将数据快速映射为固定长度的数字或哈希值。
在C语言中,哈希计算广泛应用于数据结构、密码学以及其他许多领域。
本文将介绍C语言中的哈希计算原理和常见应用。
一、哈希计算原理哈希计算的核心思想是将任意长度的输入数据映射为固定长度的哈希值。
哈希值在计算过程中不可逆,即无法通过哈希值还原出原始的输入数据。
C语言中常用的哈希计算算法包括MD5、SHA-1、SHA-256等。
在哈希计算过程中,需要选择合适的哈希函数。
哈希函数负责将输入数据分割成固定大小的块,并对每个块进行处理,最后生成哈希值。
常见的哈希函数采用位运算、位移操作和加法操作等,以确保生成的哈希值具有较好的随机性和均匀性。
二、C语言中的哈希计算函数在C语言中,可以使用各种哈希计算函数来进行哈希操作。
以下是一些常见的C语言哈希计算函数的示例:1. MD5哈希计算函数示例:```c#include <openssl/md5.h>void calculate_md5(const char* input, char* output) {unsigned char digest[MD5_DIGEST_LENGTH];MD5((unsigned char*)input, strlen(input), digest);for (int i = 0; i < MD5_DIGEST_LENGTH; i++) {sprintf(&output[i*2], "%02x", (unsigned int)digest[i]); }}```2. SHA-1哈希计算函数示例:```c#include <openssl/sha.h>void calculate_sha1(const char* input, char* output) {unsigned char digest[SHA_DIGEST_LENGTH];SHA1((unsigned char*)input, strlen(input), digest);for (int i = 0; i < SHA_DIGEST_LENGTH; i++) {sprintf(&output[i*2], "%02x", (unsigned int)digest[i]); }}```3. SHA-256哈希计算函数示例:```c#include <openssl/sha.h>void calculate_sha256(const char* input, char* output) {unsigned char digest[SHA256_DIGEST_LENGTH];SHA256((unsigned char*)input, strlen(input), digest);for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {sprintf(&output[i*2], "%02x", (unsigned int)digest[i]);}}```以上示例中,分别使用了openssl库中的MD5、SHA1和SHA256哈希函数。
数组中重复次数最多的元素c语言

数组中重复次数最多的元素c语言数组是一种常见的数据结构,可以存储多个相同类型的元素。
在程序设计中,经常需要对数组进行各种操作和处理。
其中一个常见的问题是找出数组中重复次数最多的元素。
要解决这个问题,我们可以使用哈希表(Hash Table)来统计每个元素出现的次数。
哈希表是一种根据键(Key)直接访问内存位置的数据结构,可以实现高效的查找和插入操作。
首先,我们需要定义一个结构体来表示哈希表的每个键值对,其中包括元素的值和出现的次数。
用简体中文表达如下:```typedef struct{int value; //元素的值int count; //出现的次数} KeyValuePair;```接下来,我们可以定义一个哈希表的大小,根据数组的元素值将其映射到哈希表的索引位置。
在这里,我们可以使用数组的元素值作为键,哈希表的索引作为值。
用简体中文表达如下:```#define HASH_SIZE 100 //哈希表的大小KeyValuePiar hashTable[HASH_SIZE]; //哈希表```然后,我们可以遍历数组,将每个元素的值作为键,在哈希表中对应的位置上增加计数器。
如果哈希表中不存在该键,则创建一个新的键值对,计数器初始化为1。
用简体中文表达如下:```void findMostFrequentElement(int arr[], int length){for (int i = 0; i < length; i++){int index = arr[i] % HASH_SIZE; //哈希表的索引位置//在哈希表中查找键值对int found = 0;for (int j = 0; j < HASH_SIZE; j++){if (hashTable[j].value == arr[i]){hashTable[j].count++; //计数器加1found = 1;break;}}//如果哈希表中不存在该键,则创建一个新的键值对if (!found){for (int j = 0; j < HASH_SIZE; j++){if (hashTable[j].value == 0){hashTable[j].value = arr[i];hashTable[j].count = 1;break;}}}}}```最后,我们可以遍历哈希表,找出拥有最大计数器的元素。
c语言hash函数

c语言hash函数C语言中的hash函数是一种常用的算法,用于将任意长度的数据映射为固定长度的哈希值。
哈希函数的设计是计算机科学中的一个重要问题,它在数据结构、密码学、信息检索等领域有广泛的应用。
哈希函数的核心思想是将数据通过某种算法转换成一个固定长度的哈希值,该哈希值可以用来表示原始数据。
在C语言中,哈希函数通常是通过对原始数据进行一系列的位运算、数学运算和逻辑运算来实现的。
一个好的哈希函数应该具备以下几个特点:1.一致性:对于相同的输入,哈希函数应该始终产生相同的输出。
2.高效性:哈希函数应该在很短的时间内计算出哈希值,不应该消耗过多的计算资源。
3.均匀性:哈希函数应该能够将不同的输入均匀地映射到哈希空间中的不同位置,避免产生冲突。
4.不可逆性:哈希函数应该是单向的,即从哈希值无法反推出原始输入。
在实际应用中,我们常常使用哈希函数来实现数据的索引和查找。
例如在散列表中,哈希函数将关键字映射到数组中的位置,从而实现高效的查找操作。
另外,在密码学中,哈希函数也被用于保护数据的完整性和安全性。
当我们要存储敏感信息时,可以先对数据进行哈希处理,然后存储哈希值,从而避免原始数据的泄露。
在C语言中,有很多常用的哈希函数算法,比如MD5、SHA-1、CRC等。
这些算法都有自己独特的设计思想和实现方式。
例如,MD5算法通过对输入数据进行分组、位运算和循环操作,最终产生一个128位的哈希值。
而SHA-1算法则采用了更复杂的位运算和逻辑运算,生成一个160位的哈希值。
除了这些已有的哈希函数算法,我们也可以根据具体的应用场景自己设计哈希函数。
设计一个好的哈希函数需要考虑到输入数据的特点和要求,以及哈希值的分布情况。
在设计过程中,可以采用一些常见的技巧,比如取模运算、位运算和乘法等,以保证哈希函数的性能和效果。
总结起来,C语言中的哈希函数是一种重要的算法,它在数据处理和安全保护中有着广泛的应用。
好的哈希函数能够快速、准确地计算出哈希值,并具备一致性、高效性、均匀性和不可逆性等特点。
c语言面试编程题

c语言面试编程题题目1:找出数组中出现次数最多的元素题目描述:给定一个整型数组,编写一个程序找到出现次数最多的元素,并返回该元素。
输入:整型数组输出:出现次数最多的元素示例:输入:[1, 2, 3, 1, 2, 3, 4, 1, 2, 3]输出:1解题思路:首先,我们可以使用一个哈希表来统计每个元素的出现次数,然后遍历哈希表找到出现次数最多的元素即可。
解题代码:```#include <stdio.h>#include <stdlib.h>int findMostFrequentElement(int arr[], int size) {if (size == 0) {return 0;}int maxCount = 0;int maxElement = arr[0];// 哈希表用于统计元素出现次数int* count = (int*)calloc(1000, sizeof(int));for (int i = 0; i < size; i++) {count[arr[i]]++;if (count[arr[i]] > maxCount) {maxCount = count[arr[i]];maxElement = arr[i];}}free(count);return maxElement;}int main() {int arr[] = {1, 2, 3, 1, 2, 3, 4, 1, 2, 3};int size = sizeof(arr) / sizeof(arr[0]);int mostFrequentElement = findMostFrequentElement(arr, size); printf("The most frequent element is %d\n", mostFrequentElement);return 0;}```题目2:反转字符串中的元音字母题目描述:给定一个字符串,编写一个程序反转字符串中的元音字母。
程序的源代码的相似性判别

程序的源代码的相似性判别程序源代码的相似性一、课题内容和要求对于两个C++语言的源程序代码,用哈希表的方法分别统计两个程序中使用C++语言关键字的情况,并最终按定量的计算结果,得出两份程序的相似性。
基本要求:建立C++语言关键字的哈希表,统计在每个源程序中C++关键字出现的频度, 得到两个向量X1和X2,通过计算向量X1和X2的相对距离来判断两个源程序的相似性。
例如:关键字Void Int For Char if else while do break class程序1关键字频度 4 3 0 4 3 0 7 0 0 2程序2关键字频度 4 2 0 5 4 0 5 2 0 1X1=[4,3,0,4,3,0,7,0,0,2]X2=[4,2,0,5,4,0,5,2,0,1]设s是向量X1和X2的相对距离,s=sqrt( ∑(x i1-x i2) 2 ),当X1=X2时,s=0, 反映出可能是同一个程序;s值越大,则两个程序的差别可能也越大。
测试数据: 选择若干组编译和运行都无误的C++程序,程序之间有相近的和差别大的,用上述方法求s, 对比两个程序的相似性。
二、课题需求分析1.需求分析软件的基本功能、输入/输出形式、测试数据要求。
该软件能够比较两个源程序代码的相似度。
需要用户输入两个源代码的文件名,系统会自动计算出两个程序中关键字的个数,并进行对比,而且计算出两个程序的相似度并输出,用户可以根据,系统输出相似度的大小,来估计两个程序相似的概率。
2.概要设计抽象数据类型、主程序流程及模块调用关系。
该程序用到的数据结构主要是哈希表,其次是顺序表:哈希表的功能是统计文件里出现的关键字的个数,通过++模式,该程序主要统计了C++的十个常用关键字break,char,class,do,else,for,if,int,void,while出现的频度,在Hash类里定义了一个哈希表,哈希表的大小为十个整形数据,哈希表里的十个数据是与已知的十个关键字一一对应的,顺序表用于存放处理后的数据。
a计权算法c语言

a计权算法c语言在计算机科学领域中,算法是解决问题的一种方法或步骤。
而在信息检索领域,a计权算法是一种常用的算法,用于对文本进行权重计算和排序。
本文将介绍a计权算法的原理和实现,以及如何在C 语言中使用。
让我们来了解a计权算法的原理。
a计权算法是一种基于词频和文档频率的算法,用于衡量一个词语在文本中的重要性。
它的核心思想是,一个词语在文本中的出现频率越高,并且在其他文本中出现的频率越低,那么它的重要性就越高。
在a计权算法中,首先需要计算词频。
词频是指一个词语在文本中出现的次数。
我们可以通过遍历文本,将每个词语的出现次数进行统计,得到一个词频表。
接下来,需要计算文档频率。
文档频率是指一个词语在整个文本集合中出现的文档数。
我们可以通过遍历整个文本集合,对每个词语进行统计,得到一个文档频率表。
有了词频表和文档频率表,就可以计算每个词语的a值。
a值可以通过以下公式计算:a = (1 + log(词频)) * log(文档总数 / (1 + 文档频率))其中,log表示自然对数。
通过这个公式,可以将词语的出现频率和文档频率进行综合考量,得到每个词语的a值。
需要对文本进行排序。
根据a值,可以对文本中的词语进行排序,将重要性较高的词语排在前面。
接下来,让我们来看看如何在C语言中实现a计权算法。
需要定义一个结构体来表示词语及其对应的a值。
可以使用C语言的结构体来实现:```ctypedef struct {char word[100];double a;} Word;```然后,需要实现计算词频和文档频率的函数。
可以使用C语言的哈希表来实现,将词语作为键,词频和文档频率作为值进行存储。
接下来,可以实现计算a值的函数。
根据公式,可以遍历词频表和文档频率表,计算每个词语的a值,并存储到对应的结构体中。
可以实现对文本进行排序的函数。
可以使用C语言的排序算法,根据词语的a值进行排序,将重要性较高的词语排在前面。
通过以上步骤,就可以在C语言中实现a计权算法。
程序相似性判断

程序相似性判断⼀、问题分析基本任务:对于两个C语⾔的源程序清单,⽤哈希表的⽅法分别统计两程序中使⽤C语⾔关键字的情况,并最终按定量的计算结果,得出两份源程序清单的相似性。
任务要求:C语⾔关键字的Hash表可以⾃建,也可以如实现提⽰中那样构建。
此题的主要⼯作是扫描给定的源程序,累计在每个源程序中C语⾔关键字出现的频度。
在扫描源程序过程中,每遇到关键字就查找Hash表,并累加相应关键字出现的频度。
为保证查找效率,建议Hash表的平均查找长度ASL不⼤于2。
⼆、程序设计解决⽅案:本程序根据要求和实现提⽰设计思路,⾸先要实现在哈希表中的关键字查找和统计先要设计哈希表的结构以及使⽤到的操作并进⾏实现,其次要实现对C语⾔程序中所有字符串在哈希表中进⾏查找,会多余出⼤量的⽆效查找增加哈希表的查找次数和时间复杂度,所以根据实现提⽰,采⽤查找速度更快捷、占⽤空间更⼩的键树结构进⾏过滤,所以下⼀步设计C语⾔关键字的键树结构并实现过滤操作,程序⼀边读取C 程序清单中的字符串,⼀边将字符串在键树结构中进⾏查找,如果存在则继续在哈希表中进⾏查找,查询成功⼀次则将哈希表结点中的nvalue值加⼀,记录频数,最后,实现主体函数的设计,即整个程序中主调程序的实现过程。
⽅案理论:(1)哈希表构建的具体理念本程序哈希表结构的构造⽅法采⽤较为简单且常⽤的除留余数法,以除留余数法构造哈希函数并进⾏关键字寻址,采⽤较为简单且⽅便有效的⼆次探测再散列的⽅法处理哈希结点构造中的冲突。
C语⾔有32个关键字,假设以⼆次探测再散列处理冲突,为达到ASL≤2,则要求装载因⼦a≤0.795,因关键字个数n=32,应取表长m>40。
对于⼆次探测再散列,应取4j+3型的素数,故设表长m=43。
最后根据所设表长设计Hash函数。
采⽤除留余数法,并取p=41,设hash(key)=[(key的⾸字符序号)*100+(key的尾字符序号)] mod 41冲突处理⽅法为H i+1, i+2 = ( H1± i2 ) mod 41 i = 1, 2, 3, …(2)键树构建的具体理念本题很⼤的⼯作量将是对源程序扫描,区分出C程序的每⼀关键字。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 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表空间开辟越大其冲突次数也并非一定减少。