设计哈希表实现电话号码查询系统C语言版课程设计报告.docx
《设计哈希表实现电话号码查询系统C语言版课程设计报告.docx》由会员分享,可在线阅读,更多相关《设计哈希表实现电话号码查询系统C语言版课程设计报告.docx(29页珍藏版)》请在冰豆网上搜索。
设计哈希表实现电话号码查询系统C语言版课程设计报告
设计哈希表实现查询系统
一﹑目的
通过课程设计,巩固和加深对结构体、文件、哈希表等理论知识的理解;掌握现实复杂问题的分析建模和解决方法,掌握包括问题描述、系统分析、设计建模、代码实现、结果分析等的方法;提高利用计算机分析解决综合性实际问题的基本能力;锻炼个人动手能力,历练自身素质。
哈希表实现查询系统是利用哈希表实现系统的快速查询,程序实现哈希表建表和查表,并实现对没有查找到的内容进行记录。
掌握哈希表的工作原理,熟悉建立哈希表、对哈希表冲突处理、哈希表查找等功能的实现,回顾文件读取、写入,回顾随机函数的作用。
二﹑需求分析
1.输入的形式和输入值的范围
数据输入分两种模式:
一种是将原有数据记录在old.txt文档中,由程序读入;另一种是由程序随机生成,并储存在new.txt文档中。
数据的格式为:
##、、家庭住址。
用户使用时显示菜单,用户输入菜单选项完成操作。
2.输出的形式
查找的结果显示在屏幕上。
未被查找到的内容输出到out.txt文档中。
在用户需要时,将哈希表显示在屏幕上。
3.程序所能达到的功能
根据用户的选择,从原有文档读入数据或随机生成数据,分别以##和做为关键字生成哈希表。
生成哈希表后用户可以根据相应关键字进行数据的查找,若查找到对应的数据则将数据输出到屏幕,若没有查找到对应的数据则将用户输入的查找内容输出到out.txt文档。
在用户选择显示哈希表时,显示完整的哈希表。
程序使用文字菜单的友好界面。
在数据输入时对输入内容进行范围控制。
4.初步测试计划
在old.txt文档中输入30条记录,令程序读入并分别以##和做为关键字生成哈希表,查找记录中原有的记录,查看输出数据,查找记录中没有的记录查看回馈,查看整个哈希表的数据。
令程序随机生成记录,查看new.txt文档,分别以##和做为关键字生成哈希表,查看整个哈希表的数据,分别查找原有和没有的记录,查看回馈。
三﹑概要设计
1.数据类型
定义结构体类型存储每条记录。
structData
{
charname[sizename];
charphone[sizephone];
charaddress[sizeaddress];
boolused;
}*hash_data;
2各种函数说明:
intget_hashkey(char*str,intselect)//获得关键字
voidshow(inti)//显示每条信息
voidStore(char*str)//在没有找到时输出未找到的记录,打开文件out.txt并将记录储存在文档中
voidAllshow()//输出哈希表中的记录
voidAuto_file()//随机生成数据,并将数据保存在new.txt
voidBuild_Hash(intHashType)//建立哈希表
voidFindName()//根据##查找哈希表中的记录
voidFindPhone()//根据查找哈希表中的记录
四﹑详细设计
1.头文件与定义结构体类型
#include
#include
#include
#include
structData
{
stringname;//
stringphone;
stringaddress;
};Data*hash_data;
2.定义长度
#definesizehash100
#definesizename20
#definesizephone15
#definesizeaddress40
3.获取关键字函数
intget_hashkey(char*str,intselect)
{
intKey=0,ReKey,m;
chartmp[10];
for(inti=0;i{
Key+=str[i];
}
Key%=sizehash;
if(hash_data[Key].used)
{
m=Key;
Key=-1;
if(select==1)
{
for(i=0;i<10;i++)
{
ReKey=(m+A[i])%sizehash;
if(!
hash_data[ReKey].used)
{
Key=ReKey;
break;
}
}
}elseif(select==2)
{
ReKey=m;
for(i=0;i<100;i++)
{ReKey=ReKey+1;
ReKey=ReKey%sizehash;
if(!
hash_data[ReKey].used)
{
Key=ReKey;
break;
}
}
}
}
returnKey;
}
4.产生hash表
voidBuild_Hash(intHashType){
for(inti=0;iFILE*reader=fopen(DataFile,"r");
if(reader==NULL)
{
printf("%s读取失败\n",DataFile);
fclose(reader);
exit
(1);
}
chars[100];
charseps[]=",\t";
char*name;char*phone;char*address;
intHashKey;
while(!
feof(reader))
{
fgets(s,100,reader);
if(strlen(s)>0)
{
name=strtok(s,seps);
phone=strtok(NULL,seps);
address=strtok(NULL,seps);
if(HashType==1)
{
HashKey=get_hashkey(name,HashType);}elseif(HashType==2)
{
HashKey=get_hashkey(phone,HashType);}
if(HashKey==-1)
{
printf("哈希表过小或哈希碰撞过多");
fclose(reader);
exit
(1);
}else{
strcpy(hash_data[HashKey].name,name);
strcpy(hash_data[HashKey].phone,phone);
strcpy(hash_data[HashKey].address,address);
hash_data[HashKey].used=true;
}
}
}
fclose(reader);
}
5.在没有找到时输出未找到的记录,打开文件out.txt并将记录储存在文档中
voidStore(char*str)//将查找失败记录添加到out.txt文件末尾
{
FILE*pf=fopen("out.txt","wa");//以追加的方式写入
if(pf==NULL)//判断文件是否打开成功
{
printf("创建out.txt失败\n");
fclose(pf);
exit
(1);
}
fscanf(pf,"%s",str);
fclose(pf);
}
6.输出哈希表中的记录
voidAllshow()
{
for(inti=0;i{
if(hash_data[i].used)
{
show(i);
}
}
printf("\n\n");
}
7.随机生成数据,并将数据保存在new.txt
voidAuto_file()
{
FILE*fp=fopen("new.txt","w+");
writer.open("new.txt");
if(fp==NULL)
{
printf("创ä¡ä建¡§new.txt失º¡ì败㨹!
\n\n");
fclose(fp);
exit
(1);
}
chars[100]={0};
intk=0;
srand(time(0));
for(inti=0;i<50;i++)
{
memset(s,0,100);
k=0;
//随?
机¨²产¨²生¦¨²用®?
户¡ì名?
for(intj=0;j<8;j++,k++)
{
s[k]='a'+rand()%26;
}
//随?
机¨²产¨²生¦¨²电Ì?
话¡ã号?
码?
s[k++]='\t';
for(j=0;j<12;j++,k++)
{
s[k]='0'+rand()%10;
}
//随?
机¨²产¨²生¦¨²地Ì?
址¡¤
s[k++]='\t';
for(j=0;j<20;j++,k++)
{
s[k]='a'+rand()%26;
}
fprintf(fp,"%s",s);
if(i!
=49)
fprintf(fp,"\n");
}
fclose(fp);
}
8.根据##查找哈希表中的记录
intFind_by_name(stringname)
{
inti=0;
intj=1;
intkey;
char*p;
for(key=0,p=&name[0];*p;p++)
key=key+*p;
key=key%43;
while
(1)
{
if(sign[key]=='0'&&key<=42)
{key++;j++;}
if(hash_data[key].name==name)
returnkey;
else
{
key=Handle_Random(key,i);
j++;
}
if(j==num)
return-1;
}
}
9.根据用户名查找记录
voidFindName(){
charname[10]="";
printf("请输入要查找的用户名:
");
scanf("%s",name);
inti=Find(name,1);
if(i==-1)
{
printf("无此记录\n");
Store(name);
}else{
printf("查找结果:
\n");
show(i);
}
printf("\n\n");
}
10.根据查找记录
voidFindPhone(){
charphone[12]="";
printf("请输入要查找的:
");
scanf("%s",phone);
inti=Find(phone,2);
if(i==-1)
{
printf("无此记!
\n");
Store(phone);
}else{
printf("查找结果:
\n");
show(i);
}
printf("\n\n");}
12.整个程序的流程图如下
五﹑调试分析
1.测试环境
在Windows7环境下的VisualC++6.0。
2.模块调试
随机生成数据时,对随机生成的内容的控制需要特别注意。
要注意其字符组合模式,比如生成名字是应该只有字幕,生成是应该只有数字,在随机生成是用ASCII码的规律解决。
还要注意生成字符组合的长度限制,比如应该是11位,这可以在循环语句中进行控制。
在哈希含查找时要注意取余的除数的一致,这是哈希表成立的关键点。
3.复杂度分析
使用哈希表存储记录,在执行查找是可以快捷的进行查找。
程序选用了除留余数法建立哈希函数,选用在哈希法和为随机探测再散列法。
程序设定的哈希标长为50,文件数据长度为30,则哈希表的填装因子α为0.6,则查找成功时的平均查找长度为Snr≈-In〔1-0.6〕
查找不成功时的平均查找长度为Unr≈
六﹑测试结果
1菜单:
运行软件后会出现主菜单,然后可以根据上面的提示,选择相应操作。
2以##或者查询old.txt文件中的数据:
按照提示输入##查找:
第一步输入文件中没有的##kjhyuio查找结果显示无此记录。
第二步输入hefangfang就立刻显示出正确信息。
第三步显示以##为关键字建立的哈希表。
第四步输入0退出程序。
第二步输入文件中没有的1332455查找结果显示输入不正确。
第三步显示以为关键字建立的哈希表。
第四步输入0退出程序。
3以##或者查询new.txt文件中的数据:
按照提示输入##查找:
第一步输入文件中没有的##dbfgdswe查找结果显示无此记录。
第二步输入wfnfozvs就立刻显示出正确信息。
第三步显示以##为关键字建立的哈希表。
第四步输入0退出程序。
第二步输入20973726016查找结果显示正确信息。
第三步显示以为关键字建立的哈希表。
第四步输入0退出程序。
七﹑用户使用说明
本程序运行在Windows7系统下。
程序为命令提示行文件,执行文件前请在程序同目录下的old.txt文件中输入原始数据。
程序生成的文档文件也将存放在程序同目录下。
打开程序后请根据提示选择功能。
输入“1〞程序将使用程序同目录下的old.txt文件中的数据;
输入“2〞程序将随机生成数据;
输入“0〞则会结束程序。
输入“1〞表明用##做为关键字进行查找;
输入“2〞表明用做为关键字进行查找;
用##〔〕查找时
输入“1〞用户将需要输入##〔〕进行查找;
输入“2〞程序将显示完整的哈希表;
输入“0〞则会结束程序。
用户输入##查找后,若有这条记录,程序将显示该条记录。
若未找到这条记录,则显示“没有找到这条记录!
〞,同时将输入记录在程序同目录下的out.txt文件中。
选择随机生成随据,数据同时将输出在程序同目录下的new.txt文件中。
八﹑课程设计总结
1编程前遇到一些小问题:
由于C语言我们现在学的比较浅,所以编程都是自己通过网上学习或者请教同学,对于文件应用方面我了解甚少,但是经过自己自行学习文件知识后,了解了文件方面相应的知识。
开始时程序出现了一些问题,经过修改和完善,终于解决了每个问题,使程序新建或打开文件非常好。
通过努力也把文件应运得很好。
2心得:
通过此次课程设,我巩固和加深了对哈希表、文件等理论知识的理解;掌握现实复杂问题的分析建模和解决方法;也提高了对报告书写的规范性。
本次设计哈希表实现查询系统课程设计,实现了用户通过##或者查找自己建好的old.txt文件和系统自动生成的new.txt文件中的信息。
九﹑附录
源代码
#include
#include
#include
#include
#definesizehash100
#definesizename20
#definesizephone15
#definesizeaddress40
structData
{
charname[sizename];
charphone[sizephone];
charaddress[sizeaddress];
boolused;//表示该条记录已使用
}*hash_data;
intA[10]={1,6,11,16,21,26,31,36,41,46};//伪随机数
char*DataFile;
voidAuto_file()
{
FILE*fp=fopen("new.txt","w+");
//writer.open("new.txt");
if(fp==NULL)
{
printf("创建new.txt失败!
\n\n");
fclose(fp);
exit
(1);
}
chars[100]={0};
intk=0;
srand(time(0));
for(inti=0;i<50;i++)
{
memset(s,0,100);
k=0;
for(intj=0;j<8;j++,k++)
{
s[k]='a'+rand()%26;
}
s[k++]='\t';
for(j=0;j<12;j++,k++)
{
s[k]='0'+rand()%10;
}
s[k++]='\t';
for(j=0;j<20;j++,k++)
{
s[k]='a'+rand()%26;
}
fprintf(fp,"%s",s);
if(i!
=49)
fprintf(fp,"\n");
}
fclose(fp);
}
intget_hashkey(char*str,intselect)
{
intKey=0,ReKey,m;
chartmp[10];
for(inti=0;i{
Key+=str[i];
}
Key%=sizehash;
if(hash_data[Key].used)
{
m=Key;
Key=-1;
if(select==1)
{
for(i=0;i<10;i++)
{
ReKey=(m+A[i])%sizehash;
if(!
hash_data[ReKey].used)
{
Key=ReKey;
break;
}
}
}elseif(select==2)
{
ReKey=m;
for(i=0;i<100;i++)
{ReKey=ReKey+1;
ReKey=ReKey%sizehash;
if(!
hash_data[ReKey].used)
{
Key=ReKey;
break;
}
}
}
}
returnKey;
}
voidBuild_Hash(intHashType)//产生hash表
{
for(inti=0;iFILE*reader=fopen(DataFile,"r");
if(reader==NULL)
{
printf("%s读取失败\n",DataFile);
fclose(reader);
exit
(1);
}
chars[100];
charseps[]=",\t";
char*name;char*phone;char*address;
intHashKey;
while(!
feof(reader))
{
fgets(s,100,reader);
if(strlen(s)>0)
{
name=strtok(s,seps);
phone=strtok(NULL,seps);
address=strtok(NULL,seps);
if(HashType==1)
{
HashKey=get_hashkey(name,HashType);}elseif(HashType==2)
{
HashKey=get_hashkey(phone,HashType);}
if(HashKey==-1)
{
printf("哈t希¡ê表À¨ª过y小?
或¨°哈t希¡ê碰?
撞Á2过y多¨¤!
ê?
");
fclose(reader);
exit
(1);
}else{
strcpy(hash_data[HashKey].name,name);
strcpy(hash_data[HashKey].phone,phone);
strcpy(hash_data[HashKey].address,address);
hash_data[HashKey].used=true;
}
}
}
fclose(reader);
}
voidshow(inti)
{
printf("%s\t%s\t%s\n",hash_data[i].name,hash_data[i].phone,hash_data[i].address);
}
voidAllshow()
{
for(inti=0;i{
if(hash_data[i].used)
{
show(i);
}
}
printf("\n\n");
}
intFind(char*str,intselect){
intKey=0;
intReKey;
chartmp[10];intm;
for(inti=0;i{
Key+=str[i];
}
Key%=sizehash;
if(!
hash_data[Key].used)
{
return-1;
}
if((select==1&&strcmp(hash_data[Key].name,str)!
=0)||(select==2&&strcmp(hash_data[Key].phone,str)!
=0))
{
m=Key;
Key=-1;
if(select==1)
{
for(i=0;i<10;i++)
{
ReKey=(m+A[i])%sizehash;
//if(pInfo[ReHashKey].name==str)
if(strcmp(hash_data[ReKey].name,str)==0)
{
Key=ReKey;
break;
}
}
}elseif(select==2)