数据结构课程设计实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计报告
一、设计题目:单词(词组)检索
现在有一个英文字典(每个单词都是由小写的'a'-'z'组成)单词量很大,达到 100多万的单词,而且还有很多重复的单词。此外,我们现在还有一些 Document,每个 Document 包含一些英语单词。针对这个问题,请你选择合适的数据结构,组织这些数据,使时间复杂度和空间复杂度尽可能低,并且解决下面的问题和分析自己算法的时间复杂度。
1)基本型问题
(1)选择合适的数据结构,将所有的英文单词生成一个字典Dictionary。
(2)给定一个单词,判断这个单词是否在字典 Dictionary中。如果在单词库中,输出这个单词总共出现的次数。否则输出NO。
2)扩展型问题
(3)给定一个单词,按字典序输出字典 Dictionary 中所有以这个单词为前缀的单词。例如,如果字典 T={a,aa, aaa, b, ba}, 如果你输入 a,那么输出应该为{a, aa, aaa}。
(4)给定一个单词,输出在Dictionary 中以这个单词为前缀的单词的出现频率最高的10个单词,对于具有相同出现次数的情况,按照最近(即最后)插入的单词优先级比较高的原则输出。
(5)输出Dictionary中出现次数最高的10个单词。
3)高级型问题
(6)现在我们有一些Document,每个Document 由一些单词组成,现在的问题就是给你一个word,检索出哪些 Document包含这个word,输出这些Document的DocumentID(就如同搜索引擎一样,即输入一些关键字,然后检索出和这些关键字相关的文档)。
(7)在第(6)问中,我们只考虑了一个word 在哪些Document 中的情况,我们进一步考虑2个相邻word的情况,检索出同时包含这两个相邻word的DocumentID。
4)挑战型问题
(8)现在我们再对(7)的问题进行扩展,把(7)中的只检索相邻 2个word 推广到可以检索多个word(即连续的k个word,其中k>=2),检索出同时包含k个连续word 的DocumentID。
二、设计思路:
对于(1)问,题目要求选择适当的数据结构将一百二十多万个英文单词生成一个字典。我采用经典字典树结构进行构造,每个节点包括频度,时间,和后继二十六个指针。其中频度为单词的频度,若该字母为单词的最后一个字母,则该字母的pin为该单词的频度,否则
pin为零。时间为单词最后一次出现的次序,为(4)问服务。
对于(2)问,题目要求在字典里查询指定单词,若在字典中则输出在字典中出现的次数,否则输出NO。读入字母,根据字典树进行查找。若在字典树中存在最后一个字母,且最后一个字母的频度不为零,则该单词存在,出现次数即为该字母频度。否则,该单词不存在。
对于(3)问,题目要求查找以指定单词为前缀的所有单词,并输出所有单词,若不存在,什么也不输出。我使用数组存储前缀和以此前缀为前缀的单词。若在字典树中存在这样的前缀,则从此节点按照字典顺序遍历字典树,并输出所有以此为前缀的所有单词。若不存在这样的前缀,则什么也不输出。
对于(4)问,题目要求查找以指定单词为前缀的频度最高的十个单词,并按频度高低顺序输出。若频度相同,则按照最近(即最后)插入的单词优先级比较高的原则输出。若不满十个则全部输出。我采用Node T[10]存储频度最高的前十个单词,排序使用插入排序,对频度相同的单词,比较它们的time,若time比较大,则插到前面。
对于(5)问,题目要求输出字典中频度最高的十个单词。我采用Node Top[10]存储频度最高的前十个单词,遍历字典树,按照插入排序进行排序。
对于(6)问,题目要求在若干Document中查找指定单词,若存在该单词,则输出所在Document的ID,要求输出所有存在的ID。若不存在什么也不输出。由于(6)(7)(8)问与前五问使用的文件不相同,我在编写程序时,就把前五问与后面几问分开了。我同样采用了字典树结构进行存储Document中的单词,不过字母节点变成频度、坐标和二十六个后继指针。其中坐标为单词所在Document的ID和所
在Document的第几个顺序。在此问中,按照字典树查找指定单词,并输出单词所在Document的ID。
对于(7)问,题目要求在Document中查找两个单词组成的词组。我先将读入的词组分成两个单词,分别在字典树中查找两个单词,得到两个单词的坐标。先比较两个单词的ID,若ID相同,则比较在Document中的顺序,若前后两个单词的顺序,后一个单词比前一个单词顺序大1,则输出该ID。否则不输出。
对于(8)问,题目要求在Document中查找K个单词组成的词组。由于时间的原因,我仅仅有思路,但未能将程序编写出来。我的思路是将词组拆分成K个单词,分别在字典树中查找,得出K个单词的坐标。先对k个单词的ID求交,得出在相同的ID,再比较K个单词在Document的位置是否连续,若连续则输出ID。否则不输出。
三、概要设计:
1、节点设计:
前五问:typedef struct TNode
{
struct TNode *point[26];
int pin;
int time;
}TNode;
//字典树节点,pin记录单词出现次数,time记录单词最后一次出现的次序
typedef struct Node
{
char k[40];
int flag;
int time;
}Node;
//用来存前缀最高的十个单词
2、主函数:
一至五问:void main()
{
int i;
TNode *root;
root=(struct TNode *)malloc(sizeof (struct TNode));
for (i=0;i<26;i++)
{
root->point[i]=NULL;
}
printf("程序开始运行\n\n打开文件“vocabulary.txt”开始生成字典\n");
CreateTree(root);
printf("生成字典成功\n第一问解决\n\n\n打开文件“SearchWordInVocabulary.txt”\n开始查找单词\n");
Search(root);
printf("查找结束\n结果保存在文件“SearchWordInVocabulary_Result.txt”\n第二问解决