数据结构课程设计实验报告Word格式.docx
《数据结构课程设计实验报告Word格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计实验报告Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
(7)在第(6)问中,我们只考虑了一个word在哪些Document中的情况,我们进一步考虑2个相邻word的情况,检索出同时包含这两个相邻word的DocumentID。
4)挑战型问题
(8)现在我们再对(7)的问题进行扩展,把(7)中的只检索相邻2个word推广到可以检索多个word(即连续的k个word,其中k>
=2),检索出同时包含k个连续word的DocumentID。
●
一、需求分析
本演示程序中,Vocabulary文件夹下的vocabulary.txt是英文字典的数据总共有120多万个单词,由此生成一个字典树。
SearchWordInVocabulay文件夹下对应的是问题
(2)中的数据,其中SearchWordInVocabulary.txt是要在字典中检索的数据,需要生成一个SearchWordInVocabulary_Result.txt来保存检索的结果,其中结果的格式为对于每个输入的Word,首先输出CASEID:
ID表示这个Word是输入的第ID个WORD,然后如果这个Word在字典中,输出这个Word出现的次数,否则输出“NO”。
TotPrefixWord文件夹下对应的是问题(3)中的数据,其中TotPrefixWord.txt是要在字典中检索的前缀的数据,需要生成一个TotPrefixWord_Result.txt文件来保存检索的结果,对于TotPrefixWord.txt中的一个输入prefix,输出格式同样是先输出CASEID:
,然后按字典序输出字典中以prefix为前缀的所有word(不能重复)。
PrefixFrequence文件夹下对应的是问题(4)中的数据,其中PrefixFrequence.txt是要在字典中检索的前缀的数据,需要生成一个PrefixFrequence_Result.txt文件来保存为检索的结果,对于PrefixFrequence.txt中的一个输入prefix,输出格式同样是先输出CASEID:
,然后按(4)中定义的优先级输出字典中优先级最高的10个以prefix为前缀word和这个word出现的次数,如果不足10个,就全部输出)。
对于问题(5),需要生成一个MostFrequenceWord.txt文件包含出现次数最多的10个单词和单词出现的次数。
2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示提示信息,告诉用户已完成那些题目。
3.程序执行的命令包括:
(1)构造哈希表;
(2)查找单词出现的次数;
(3)找出前缀相同的单词并输出;
(4)找出前缀相同出现次数最多的十个单词;
(5)找出字典中出现次数最多的十个单词;
(6)结束。
4.测试数据
根据要求得出结果,由给的软件判断结果是否正确。
2、概要设计
本程序包括五个模块:
(1)主程序模块;
(2)构造哈希表模块;
(3)查找单词模块;
(4)查找前缀相同单词模块;
(5)查找前缀相同出现次数最高的十个单词模块;
(6)查找出现次数最多的十个单词模块;
(7)模块调用图:
主程序模块
构造哈希表模块
查找单词模块
查找前缀相同单词模块
查找前缀相同出现次数最高的十个单词模块
查找出现次数最多的十个单词模块
3、详细设计
1、数据结构定义
#include<
stdio.h>
string.h>
stdlib.h>
malloc.h>
#defineMAX100000
//===========
typedefstruct{
char*Pword;
//存储的单词地址
inttimes;
//单词出现的次数
}Data,*PData;
//存储结构体
DataDic[MAX];
}RedType;
RedTypedatas[MAX];
longintlength;
}HeapType;
HeapTypeheaps;
typedefstructTrie_node_stru
{
intcount;
//记录该处终结的单词个数
structTrie_node_stru*next[26];
//指向各个子树的指针,下标0-25代表26字符
inttag;
}TrieNode,*Trie;
2、哈希表的创建
unsignedintELFHash(char*str)/*ELFHashFunction*/
{
unsignedinthash=0;
unsignedintx=0;
while(*str)
{
hash=(*str++)+(hash<
<
4);
if((x=hash&
0xF0000000L)!
=0)
{
hash=hash^(x>
>
24);
hash=hash&
(~x);
}
}
return((hash&
0x7FFFFFFF)%39989);
}
voidCreatHT()
inti;
printf("
初始化哈希表,请稍后...\n\n"
);
for(i=0;
i<
MAX;
i++)
Dic[i].times=0;
Dic[i].Pword=0;
}
哈希表初始化完成\n"
intGetTimes(charch,inti)
if('
\n'
==ch||-1==ch)
returni+1;
else
returni;
3、哈希表的初始化和建立
intPush_hash(char*word,unsignedintpos)
inttag=0;
unsignedinti=pos;
intj=0;
if(Dic[pos].times==0)
Dic[pos].Pword=word;
Dic[pos].times++;
if(Dic[pos].times!
=0)
if(strcmp(Dic[pos].Pword,word)==0)
Dic[pos].times++;
tag=1;
}
else
pos=(pos+1)%MAX;
tag=Push_hash(word,pos);
returntag;
intRead()
FILE*fp;
charch=0;
unsignedintPOS=1;
inti=0/*单词的下标*/;
intTJ=0;
\t开始构建哈希表...\n"
\n请稍等……\n"
if(!
(fp=fopen("
vocabulary.txt"
"
r"
)))
printf("
Cannotopenthefile...Creat_Hash_List\n"
exit(0);
while(!
(feof(fp)))
char*Inf,tmp[50]="
"
;
intj=0;
Inf=Allwords+i;
do{
ch=fgetc(fp);
TJ=GetTimes(ch,TJ);
if(ch=='
{
tmp[j]=Allwords[i]='
\0'
}
else
tmp[j]=Allwords[i]=ch;
i++;
j++;
}while(ch!
='
&
!
feof(fp));
POS=ELFHash(tmp);
if(!
feof(fp))
if(Push_hash(Inf,POS))
i=Inf-Allwords;
if(-1==*Inf)
break;
Push_hash(Inf,POS);
break;
}//while
TJ--;
fclose(fp);
\t哈希表构建over!
\n单词共有:
%7d个(重复计数)\n\n"
TJ);
。
return0;
longintNoRepetition()
longintj=0;
if(Dic[i].times!
returnj;
4、创建字典
voidSearch_Hash()
chara[50];
chartag;
unsignedintposs;
请输入您要搜索的单词:
gets(a);
poss=ELFHash(a);
strcmp(Dic[poss].Pword,a))
查询到此单词!
共出现%7d次\n"
Dic[poss].times);
else
while(Dic[poss].times&
poss++;
Dic[poss].times)
printf("
查无此词!
\n\n"
继续查询?
Y/N"
scanf("
%c"
&
tag);
getchar();
if(tag=='
Y'
||tag=='
y'
Search_Hash();
5、最热的10个单词的查找
voidstart_heap(longintlongs)
inti,j=1;
初始化堆..\n"
if(Dic[i].times)
heaps.datas[j].times=Dic[i].times;
heaps.datas[j].Pword=Dic[i].Pword;
heaps.length=longs;
堆初始化完成\n"
voidHeapAdjust(HeapType&
H,ints,intm){//算法10.10
//已知H.r[s..m]中记录的关键字除H.r[s].key之外均满足堆的定义,
//本函数调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆
//(对其中记录的关键字而言)
intj;
RedTyperc;
rc=H.datas[s];
for(j=2*s;
j<
=m;
j*=2){//沿key较大的孩子结点向下筛选
if(j<
m&
H.datas[j].times<
H.datas[j+1].times)++j;
//j为key较大的记录的下标
if(rc.times>
=H.datas[j].times)break;
//rc应插入在位置s上
H.datas[s]=H.datas[j];
s=j;
H.datas[s]=rc;
//插入
}//HeapAdjust
voidHeapSort(HeapType&
H){//算法10.11
//对顺序表H进行堆排序。
RedTypetemp;
for(i=H.length/2;
i>
0;
--i)//把H.r[1..H.length]建成大顶堆
HeapAdjust(H,i,H.length);
for(i=H.length;
1;
--i){
temp=H.datas[i];
H.datas[i]=H.datas[1];
H.datas[1]=temp;
//将堆顶记录和当前未经排序子序列Hr[1..i]中
//最后一个记录相互交换
HeapAdjust(H,1,i-1);
//将H.r[1..i-1]重新调整为大顶堆
}//HeapSort
voidPrintFQ(HeapType&
H,longinttotal)
FILE*out;
longinti;
if((out=fopen("
MostFrequenceWord.txt"
w"
))==NULL)
cannotopenfile\n"
for(i=total;
i>
total-10;
i--)
fprintf(out,"
%s\n%d\n"
heaps.datas[i].Pword,heaps.datas[i].times);
四、程序使用说明及测试结果
1.程序使用说明
(1)本程序的运行环境为VC6.0
2.测试结果
根据所给的软件,测出所得文件正确
3.调试中的错误及解决办法(遇到时给出)
4.运行界面
由于文件内没有单词,暂时是这样。
五、实验总结
在这次程序的编写中,从来没有哪一次编程会用这么长的时间,刚开始就被题目的背景懵了,不知道从哪儿下手来写这个程序,后来一步步来,慢慢有了大体的框架,分布完成这个程序,首先花费了不少时间理解书上的算法,虽然有些挺难懂的,但是在空间和时间上都是很节约的算法。
指向结构体的指针和指向字符型数据的指针的指针在一定程度上比较难理解。
还有文件函数的应用很不熟悉,有些函数还是上网找的资料才会运用的,这次编程还有一个问题,就是自己虽然理解书本上的算法,可是自己不能独立写出来,这让我有点担心数据结构的考试,此次编程对我的启发是,以后要通过编程调试来做到对数据结构的深度了解。
只有通过实际编程,调试,找到错误,才能去改正它,才能做到真正的懂得。
这个程序的设计开始很不顺利,在实际编程过程中,许多问题都是我未曾预料到的,一些小的错误很难发现,得花大量的时间才能找到。
因此我觉得,只把教材中的东西理解是远远不行的,必须在不断地编程中锻炼对数据结构的理解与应用,也只有不断训练,才能真正提高自己的编程能力。
说实话,这两个星期对我的锻炼真的很大,我一直以为我的C语言学的还不错,这次课程设计不仅是对我编程能力极大的提高,更加增加了我对C语言的兴趣,最喜欢自己的程序编出来的那份喜悦。