文学研究助手(数据结构课程设计)0204192333
- 格式:pdf
- 大小:751.71 KB
- 文档页数:19
石河子大学C++课程设计论文:2008年6月30日目录一.编程目的: (2)二.设计要求: (2)三.各函数功能说明: (2)四.输出结果: (6)五.程序结构图: (7)六.总结: (7)参考资料: (8)文学研究助手电信07-2班陈龙2007082044一.编程目的:温学研究人员需要统计某篇英文小说中某些形容词的出现次数和位置,试写出一个实现这一目标的文字统计系统,成为“文学研究助手”。
二.设计要求:1、英文小说存放在一个文本文件中;2、带统计的额词汇集合要以此输入完毕,即统计工作必须在程序的以此运行后全部完成;3、程序的输出结果是每个词的出现次数和出现位置所在的行号;4、格式自行设计。
三.各函数功能说明:函数源代码以及函数的功能:#include<fstream> //头文件fstream#include<iostream>#include<string>using namespace std;//函数jisuanvoid jisuan(const char *input){ifstream in; /*定义一个文件输入流对象: inifstream 对象打开并从文件中输出信息到别的空间*/char *s=new char[266]; //定义读取字符行schar *token; //定义分割字符tokenchar seps[]=" "; //定义按空格分割文件int i=0,j=0; //定义i,出现的个数;j,出现位置的行数in.open("文本.txt"); //此语句用来打开文件if(!in) //如果无法读入则显示:"文件错误"{cout<<"文件错误!"<<endl;}for(;in;) //利用for循环来逐个比较{in.getline(s,255); //读取一行j++; //在读取一行后,行数j进行一次自加运算token =strtok(s, seps); // 这里获得第一个子串/*注:strtok(s, seps)的作用是分解字符串为一组字符串。
数据结构课程设计:文本编辑(最后附完整代码)一.问题描述---------------------------------------------1二.设计思路---------------------------------------------1三.系统实现功能1.建立单链表-------------------------------------------22.显示文章内容---------------------------------------- 33.查找文章语句-----------------------------------------34.删除文章语句-----------------------------------------55.替换文章语句-----------------------------------------76.统计文章字数-----------------------------------------107.写入文本结束程序--------------------------------------10四.系统不足及需改进分------------------------------------11五.文件清单说明------------------------------------------11六:附录-------------------------------------------------12一:问题描述本次我所做的课程设计为:文本编辑,主要内容是对中文文本的显示、查找、删除、替换、统计、写入文本。
在程序选择功能后根据提示,输入任意长度中文语句即可对文章进行操作。
二:设计思路文本编辑,顾名思义就是对一遍文章进行编辑,我所设计的是对中文的编辑。
中文有两个字节(汉字、标点),通常情况下通过文件输入流仅仅可以取一个字节或者是以空格为分隔符取单词这仅仅对英文的文章适用,周六周日我从网上搜索相关方法,未找到一条切实可用的对中文字符操作的方法。
文学研究课程教学大纲文学研究课程教学大纲第一部分:引言文学研究是一门旨在深入探讨文学作品及其背后的文化、社会和心理因素的学科。
本课程旨在帮助学生发展批判性思维和文学分析能力,并培养他们对文学作品的深入理解和欣赏能力。
本教学大纲将提供一个详细的课程框架,包括教学目标、教学内容、教学方法和评估方式。
第二部分:教学目标1. 培养学生对文学研究的兴趣和理解。
2. 发展学生批判性思维和文学分析能力。
3. 培养学生的学术写作和口头表达能力。
4. 培养学生的团队合作和研究项目管理能力。
第三部分:教学内容1. 文学研究基础知识- 文学研究的定义和目的- 文学作品的基本元素和类型- 文学理论和研究方法2. 文学作品分析- 文学作品的结构和风格分析- 文学作品的主题和意义分析- 文学作品的背景和历史分析3. 跨文化文学研究- 文学作品在不同文化背景下的比较研究 - 跨文化文学作品的翻译和传播研究4. 文学批评与诠释- 不同文学批评理论和方法的介绍- 文学作品的解读与批评分析5. 学术写作与口头表达- 学术论文写作和文献检索技巧- 学术会议报告和口头表达技巧6. 团队合作与研究项目- 团队合作与分工管理- 研究项目策划与执行第四部分:教学方法1. 讲课- 教师通过讲课向学生介绍文学研究的基本概念、理论和方法。
2. 小组讨论- 学生分成小组进行文学作品的分析和讨论,培养学生的批判性思维和团队合作能力。
3. 研究项目- 学生通过研究项目的策划和执行,培养学生的研究能力和项目管理能力。
4. 个人写作- 学生完成个人学术论文,培养学生的学术写作能力和批判性思维能力。
第五部分:评估方式1. 学术论文- 学生完成一篇学术论文,评估其学术写作能力和文学分析能力。
2. 口头报告- 学生进行一次学术会议报告,评估其口头表达能力和文学理解能力。
3. 小组项目- 学生完成一个小组研究项目,并进行报告,评估其团队合作能力和研究项目管理能力。
数据结构1:姓名:陈东:学号:0706121462一、【实验目的】、【问题描述】三、【基本要求】四、【实验环境】五、【测试数据及其结果】六、【实验源代码】【实验目的】本次实习的主要目的是熟悉串类型的实现方法和文本模式匹配方 熟悉一般文学处理软件的设计方法,较复杂问题的分解求精方法。
【问题描述】文学研究人员需要统计某篇英文小说中某些形容词的出现次数和 位置。
试写一个是实现这一目标的文字统计系统,称为“文学研究助手”【基本要求】英文小说存于一个文本文件中待统计的词汇集合要一次输入完毕,即统计工作必须在程序的一次运行之后就全部完成。
果是每个词的出现次数和出现位置所在行的行数,格式自行设计。
四、【实验环境】Windows7, VC++6.0以自己的C 源程序模拟英文小说,C 语言的保留字集作为待统计的词汇集。
法,程序的输出结五、 【测试数据及其结果】六、【实验源代码】#i ncludevstdio.h> #in clude<stdlib.h> #i ncludeviostream.h> #defi ne MAXSTRLEN 255 #defi ne OK 1 #defi ne ERROR 0 #defi ne OVERFLOW 0typ edef char HStri ng[MAXSTRLEN+1]; typ edef int status; int n ext[MAXSTRLEN]; char *chars;typ edef struct{char *ch; int len gth;}SStri ng;char* ToStri ng(char array[], i nt array_size)// 字符数组转换成字符串{ "char *p;int i;P = (char*)malloc(array_size + 1);for(i = 0; i < array_size; i++)*(p+i) = '0' + array[i]; }*(p+i) = '\0'; return p;}status StrAssign(SString &T,char *chars)// 生成一个其值等于串常量chars 的串T {int i;int j;char *c;for(i=0,c=chars;*c!='\0';++i,++c);if(!i){T.ch=NULL;T.le ngth=0;}else{if(!(T.ch=(char *)malloc(i *sizeof(char))))exit(OVERFLOW);for(j=0;j<i;j++){T.ch[j]=chars[j];}T.le ngth=i;return OK;}void get_next(SString T,int next[])// 求next 值{"int j=1,k=0;n ext[1]=0;while(j<T.le ngth)//abaabcac{if(k==0||T.ch[k-1]==T.ch[j-1]){++j;++k; n ext[j]=k;}else k=n ext[k];}} int Index(SString S,SString T,int pos)// 匹配算法kmp {int i=po s,j=1;while(i!=S.le ngth+1 &&j!=T.le ngth+1) {if(j==0||S.ch[i-1]==T.ch[j-1]){j++;i++;} elsej=n ext[j];}if(j>T.le ngth-1)return (i-T.le ngth); elsereturn 0;void find(SString keys)// 查找单词{status StrAssig n( SStri ng &T,char *chars);int coun t=0;SStri ng T;HStri ng text;int i=1,j=0;FILE *fp;if(!(fp=fo pen( "1.txt","r"))){prin tf(" Open file error!\n"); exit(0);}get_ next(keys, next);while(!feof(fp)){fgets(text,MAXSTRLEN,fp);ToStri ng(text, sizeof(text)/sizeof(text[O])); chars=text;StrAssig n( T,chars);j=ln dex(T,keys,j+1);if(j!=0){coutvv"row="vvivv",col="vvjvve ndl; coun t++;while(j!=0){j=ln dex(T,keys,j+1);if(j!=0){ coutvv"row="vvivv",col="vvjvve ndl; coun t++;}}i++;}coutvv" nu mber is:"<<co un t<<e ndl;void main(){SStri ng S;char words[20];int n,i;prin tf("How many words do you want to find?(n <10 )\n"); sca nf("%d",&n); printfC'P lease input the words you want to fin d:\ n"); for(i=0;i< n;i++) {cin> >words;ToStri ng(words, sizeof(words)/sizeof(words[0])); chars=words;cout<<"the "vvcharsvve ndl;StrAssig n( S,chars);fin d(S);。
题目:文学研究助手【问题描述】文学研究人员需要统计某篇英文小说中某些形容词的出现次数和位置。
试写一个实现这一目标的文字统计系统,称为“文学研究助手”。
【基本要求】英文小说存放于一个文本文件中。
待统计的词汇集合要依次输入完毕,即统计工作必须在程序的一次运行之后就全部完成。
程序的输出结果是每个词的出现次数和出现位置所在行的行号,格式自行设计。
【选作内容】(1)模式匹配要基于KMP算法(2)整个统计过程中只对小说文字扫描一遍以提高效率实验完成情况:②作内容与基本要求都已完成。
②附加了二个功能:算出了所查询的关键词在其出现行的具体位置和在此行出现的次数。
③序共达376行。
程序特色之处:A、用了KMP算法,大大提高了运算速率B、熟练且灵活地运用了链表知识C、熟练且灵活地运用了结构体知识概要设计:【抽象数据类型定义】ADT数据对象:英文字母、空格和标点符号的集合数据关系:其集合构成一篇可读性的文章基本操作:InitList(&L)操作结果:构造一个空链表;InitList_node(&L)操作结果:构造一个总链表里的分链表;copy( &T, chars) (&L)初始条件:已知chars 操作结果:chars数组中的字符付给T.ch;并计算出chars 的长度赋给T.lengthCreateNode(&sl, str)这个函数建立的是总链表里面的结点初始条件:已知str操作结果:建立sl结构体中某要素的节点,并将str相应值赋值给slCreateNode_node (&sl, str)这个函数建立的是总链表里面分链表的结点初始条件:已知str 操作结果:建立sl结构体中某要素的节点,并将str相应值赋值给sladdnode(&ls, link)这个函数建立的是总链表初始条件:已知ls和link 操作结果:将link附加到ls后面add_node(&ls, link)这个函数建立的是总链表里分链表初始条件:已知ls和link 操作结果:将link附加到ls后面Index_KMP (s, t, pos)初始条件:已知字符串s,t 操作结果:找出s中与t相同的开始位置IsNotCharactor(ch)初始条件:已知字符ch操作结果:判断ch是否为英文字母ShowList_node(L)初始条件:已知一个链表的头结点操作结果:将链表的中信息打印出来,并将链表的某些信息再传递下去ShowList(L)初始条件:已知L的相关信息操作结果:打印出L的相关信息find(&stringLinkList, hstrLine, row)初始条件:已知stringLinkList, hstrLine, row操作结果:在串数据链表stringLinkList,读出查找的串strkey,与传入的串hstrLine匹配如果成功将匹配的次数与行数row,写入相对应的行行数据链表Next(s, j)初始条件:已知s,j操作结果:KMP模式匹配的next函数,即找出自身匹配Count_KMP(s, t, pos)初始条件:已知字符串s和t,pos操作结果:求串t在s中出现的次数程序使用说明A.输入正确的打开文件方式,例如:h:\code.txtB.输入所要查询的单词,每输入一个单词就按回车,并最后以符号“#”结束、【程序模块调用关系】A 结构体调用情况整个结构体框架主要以建立两层链表为主体。
【问题描述】 文学研究人员要统计某篇英文小说中某些形容词的出现次数和位置.试写一个实现这一目标的文学统计表,称为"文学研究助手" 【基本要求】a。
英文小说存在于一个文本文件中.待统计的词汇集合要一次输入完毕,即统计工作必须 在程序的一次运行之后完成.程序的输出结果是每个词的出现次数和出现位置所在行的行号, 格式自行设计b。
模式匹配要基于 KMP 算法 c。
整个统计过程中只对小说文字扫描一次,以提高效率 【测试数据】以当前的源程序文件作为测试目标【实现提示】约定小说中的词汇一律不跨行【思路演示】【代码过程】 1。
Try to write a text to achieve this objective statistical system, known as the literary research assistants. English novel stored in a text file. Statistical terms to be set to enter the end, that is, the statistical work program must be run after a fully completed. Process the output result is the emergence of each word occurrence frequency and the line number where the line, the format design.1. #include <iostream> 2. #include <string>3. using namespace std; 4. #include <> 5. struct word 6. { 7. int line; 8. int time; 9. word * next; 10. }; 11. struct words 12. { 13. char word_re[20]; 14. int check; 15. int time_t; 16. words * next_s; 17. word * next; 18. }; 19. words * input(words * head); //比較並儲存信息時候所用的函數 20. words * output(words * head); //單純輸出直觀數據時候所使用的函 21. words * input(words * head) 22. { 23. int count=0; 24. int line=0; //記錄行數所使用到的變量 25. int time_words=0; 26. head->next_s=new words; 27. int check=1; 28. words * insert=new words; 29. word * insert_word=new word; 30. insert=head->next_s; 31. cout<<"请输入需要查询的单词"<<endl; 32. while(check) 33. { 34. cin>>insert->word_re; 35. insert->time_t=0; 36. insert->check=0;37. insert->next=new word; 38. cout<<"还希望搜索其他的单词么,1 继续,0 停止"<<endl;39. cin>>check;40. if(check>=1)41. {42.insert->next_s=new words;43.insert=insert->next_s;44. }45. }46. insert->next_s=NULL;47. insert=head->next_s;48. while(insert!=NULL)49. {50.cout<<insert->word_re<<endl;51.insert=insert->next_s;52. }53. insert=NULL;54. int time=0;55. int time_gk=0,time_wt=0;56. char compare[3]=" @";57. char getkey[32];58. char * word_tair;59. FILE * getword;60. if((getword=fopen("","r"))==NULL)61. {62.cout<<"error";63.return 0;64. }65. char word_c[80]; 66. while(fgets(word_c,80,getword)!=NULL) //讀取一行中的 80 個字符67. {68.line++;69.time_words=0; //尋找的字符出現的次數70.time_gk=0; //儲存用來比較的字符串所使用的變量71.time_wt=0; //在儲存行字符串的變量中定位72.word_tair=NULL;73.word_tair=word_c;74.time=strlen(word_tair);75.cout<<time;76.cout<<word_tair<<endl;77.while(word_tair[time_wt]!='\n')78.{79.time_gk=0;80.if((word_tair[time_wt]<='z'&&word_tair[time_wt]>='a')||(word_tair[time_wt]<='Z'&&word_tair[time_wt]>='A')||word_tair[time_wt]=='-')81.{82.83.while((word_tair[time_wt]<='z'&&word_tair[time_wt]>='a')||(word_tair[time_wt]<='Z'&&word_tair[time_wt]>='A')||word_tair[time_wt]=='-')84.{85.86.getkey[time_gk]=word_tair[time_wt];87.time_wt++;88.time_gk++;89.} //讀取出一個單詞,並儲存在新的變量中90. getkey[time_gk++]='\0';91. insert=head->next_s;92. while(insert!=NULL)93. {94.if(!strcmp(insert->word_re,getkey))95.{96.count=insert->check;97.insert->check++;98.insert_word=insert->next; //判斷是否是相同的單詞99.while(count>0)100.{101.insert_word=insert_word->next;102.count--;103.}104.insert_word->line=line;105.insert_word->time=time_words;106.insert_word->next=NULL;107.insert_word->next=new word;108.break;109.} //儲存相應信息110.insert=insert->next_s;111.}112.time_words++;113.}114.if(word_tair[time_wt++]=='\n')115.break;116.117. } 118. } 119. cout<<endl; 120. return head; 121. } 122. //輸出的函數:123. words * output(words * head)124. {125. int time=0;126. words * first=head->next_s;127. words * insert=first;128. word * insert_word=new word;129. while(insert!=NULL)130. {131. cout<<insert->word_re<<"单词共出现了"<<insert->check<<"次"<<endl;132. insert_word=insert->next;133. while(insert->check>time)134. {135.time++;136.cout<<"第"<<time<<"次出现在"<<insert_word->line<<"行,第"<<insert_word->time+1<<"个单词"<<endl;137.insert_word=insert_word->next;138. } 139. insert=insert->next_s; 140. time=0; 141. } 142. return head; 143. } 144. int main() 145. { 146. words * head_emp=new words; 147. strcpy(head_emp->word_re,"this is empty"); //母鏈的頭賦空 148. head_emp->check=-1; 149. head_emp->time_t=0; 150. head_emp->next=NULL; 151. input(head_emp); 152. output(head_emp); 153. return 0; 154. 155. }。
题号:十题目:西文图书管理1.需求分析图书管理系统对象有两个,包括读者和管理员。
读者的需求:借书,还书,续借,查询当前所借书籍还书截至日期,查询借阅历史,修改登陆密码。
其中借书可以根据书号和书名两种方式查询借阅。
管理员的需求:采编入库,清除库存,注册读者,删除读者,根据书号查询书籍,修改管理员用户名和密码。
2.设计2.1设计思想(1)数据与操作特性:有搜索,插入,删除操作。
而数据有:读者信息,书籍信息,读者借阅书籍历史信息,书籍读者借阅历史信息,读者当前所借书籍信息。
(2)数据结构设计:数据的逻辑结构有线性结构和树形结构。
根据书号和书名建立两个B-树,便于读者查询借阅,其中关键字设置为书籍指针,便于找到书籍后直接进行修改书籍信息。
读者和书籍的信息从文件中读取,由于会不断注册和删除读者以及新增删除书籍,因此书籍和读者的信息采用单链表存储。
读者的借阅历史和书籍的读者历史,都采用数组的形式存储,为了节省存储空间,每个借阅历史数组最大空间为15。
超过15个借阅历史,则删除最早的借阅历史。
2.2设计表示(1)数据类型定义typedef struct//日期结构体类型{int year;//记录年int month;//记录月int day;//记录日}Date;//记录借阅者所借书籍的信息结构体typedef struct{char bookID[15];//书号char name[15];//书名char writer[15];//作者Date bordate;//借阅时间Date backdate;//还书时间int flag;//是否续借,续借为1.否则为0}BookHistory;//记录借阅者当前所借书籍的信息结构体typedef struct{char bookID[15];//书号char name[15];//书名char writer[15];//作者Date bordate;//借阅时间Date lastdate;//最后还书期限int flag;//是否续借,续借为1.否则为0}BookRec;//记录书籍被借阅的读者记录typedef struct{char readerID[15];//记录读者的借阅证号char readername[15];//读者的名字Date bor;//记录读者的借书日期Date back;//记录读者的还书日期int flag;//借阅者是否有续借迹象(flag取值0或者1)}ReaderHistory;//记录读者信息的结构体类型(允许读者同时借阅五本书,每本书支持续借一次)typedef struct{char readerID[12];//记录读者的借书证号,一般是学号char name[15];//读者的名字char password[16];//读者登陆密码int bn;//读者现在所借书籍数量,最大数量为5本BookRec rec[5];//读者现在所借书籍int hn;//总借阅数量//R_LQueue *R_LQH;BookHistory bh[15];//记录读者的借阅记录,规定链式队列的最大节点个数为15,来节省空间}Reader;//记录书的信息的结构体类型typedef struct{char bookID[15];//书号char title[15];//记录书名char writer[15];//记录著者int currentnum;//书现存量int totalnum;//书总存量int bortimes;//被借的历史总次数//B_LQueue *B_LQH;ReaderHistory RH[15];//借书者记录,规定链式队列的最大节点个数为15,来节省空间}Book;//根据书名为关键字的B-树的结构体类型typedef struct Namenode//根据书名为关键字建立的B树{int n;//记录结点中的关键字(即书号)个数Book *key[MAXM];//key[0...n-1],Maxsize个关键字(即书名)域struct Namenode *par;//指向父结点的指针域struct Namenode *chd[MAXM];//ptr[0...n],MAXM个指向子结点的指针域}BTNamenode;typedef struct///根据书名建立的B树的搜索结果{BTNamenode *pt;////指向找到的节点指针int i;//所找关键字在节点里的位置int tag;//查找成功值为1,查找失败值为0}NameResult;//根据书号为关键字的B-树的结构体类型typedef struct IDnode//根据书号为关键字建立的B树{int n;//记录结点中的关键字(即书号)个数Book *key[MAXM];//key[0...n-1],Maxsize个关键字(即书号)域struct IDnode *par;//指向父结点的指针域struct IDnode *chd[MAXM];//ptr[0...n],MAXM个指向子结点的指针域}BTIDnode;typedef struct///根据书号建立的B树的搜索结果{BTIDnode *pt;////指向找到的节点指针int i;//所找关键字在节点里的位置int tag;//查找成功值为1,查找失败值为0}IDResult;//从文件中读取书籍数据后存储在单链表里typedef struct BookNode{Book SLbook;struct BookNode *next;}BookSLNode;//从文件中读取学生数据后存储在单链表里typedef struct ReaderNode{Reader SLreader;struct ReaderNode *next;}ReaderSLNode;2.3详细设计(1)登陆界面login():有管理员和读者登陆,都必须输入密码和用户名。
文学研究助手一、问题描述:文学研究人员需要统计某篇英文小说中某些形容词的出现次数和位置。
试写一个实现这一目标的文字统计系统,称为“文学研究助手”。
英文小说存于一个文本文件中。
待统计的词汇集合要一次输入完毕,即统计工作必须在程序的一次运行之后就全部完成。
程序的输出结果是每个词的出现次数和出现位置所在行的行号,格式自行设计。
二、需求分析:1、文本串非空且以文件形式存放,统计匹配的词集非空。
文件名和词集均由用户从键盘输入;2、“单词”定义:由字母构成的字符序列,中间不含空格字符且区分大小写;3、待统计的“单词”在文本串中不跨行出现,它或者从行首开始,或者前置若干空格字符;4、在计算机终端输出的结果是:单词,出现的次数,出现的位置所在行的行号,同一行出现两次的只输出一个行号;5、测试数据:文本文件为本次实习中的word.txt:待统计的词集:he she it has to here can not is was三、概要设计:拟采用对两个有序表进行相互比较的策略进行“单词匹配”。
程序中将涉及下列三个抽象数据类型:1. 定义“单词”类型:ADT Aword{数据对象:D={Si | Si ∈标准c字符串集合,i = 1,2,3,…….,n,n ≥0}数据关系:R1={<Si-1,Si>} | Si-1,Si ∈D,i = 1,2,3,…..,n}基本操作:NewWord(WordType *nw,Sequence cha)初始条件:cha为字符序列;操作结果:生成一个其值为给定字符序列的单词;WordCmp(WordType wd1,WordType wd2)初始条件:单词wd1和单词wd2已存在;操作结果:若wd1<wd2,则返回-1;若wd1=wd2,则返回0;若wd1>wd2,则返回1;PrintWord(WordType wd)初始条件:单词wd已存在;操作结果:在计算机终端上显示单词wd;}ADT AWord2. 定义有序表类型:ADT OrderList{数据对象:D={Si | Si ∈AWord,i = 1,2,3,…….,n,n ≥0}数据关系:R1={<Si-1,Si>} | Si-1,Si ∈D,Si-1<S,i = 1,2,3,…..,n}基本操作:InitList(OrderList *L)操作结果:构造一个空的有序表;DestroyList(OrderList *L)初始条件:有序表L已存在;操作结果:销毁L的结构,并释放所占空间;LocateElem(OrderList L,ElemType e,LinkType *q)初始条件:有序表L已存在;操作结果:若有序表L中存在元素e,则q指示L中第一个值为e的元素的位置,并返回函数值FRUE;否则q指示第一个大于e的元素的前驱的位置,并返回函数值FALSE;InsertAfter(OrderList *L,LinkType q,LinkType s)初始条件:有序表L已存在,q指示L中一个元素;操作结果:在有序表L中q指示的元素之后插入元素s;ListCompare(OrderList La,OrderList Lb,EqelemList *s)初始条件:有序表La和Lb已存在;操作结果:以s返回其中相同元素;}ADT OrderList3. 定义单词文本串文件类型如下:ADT TextString{数据对象:D={Si | Si ∈标准c字符集,i = 1,2,3,…….,n,n ≥0};数据关系:D中字符被“换行符”分割成若干行,每一行的字符间满足下列关系:R1={<Si-1,Si>} | Si-1,Si ∈D,i = 1,2,3,…..,n}基本操作:四、详细设计1、主程序中的宏定义:#define MAXSIZE 1000 //字符空间的最大容量#define MAXLEN 20 //单词的最大长度#define MAXNUM 16 //一行中单词最多个数#define FALSE 0#define TRUE 12、存储结构/*** 堆结构的定义*/typedef struct{char stores[MAXSIZE];int freep; /*当前可用空间开始位置*/}HeapSpace;HeapSpace sp;/*** 单词数据类型定义*/typedef struct{ //单词在堆中的位置描述int stadr; /*单词在对空间中的开始位置*/int len; /*单词长度*/}WordType;typedef struct{ //单词描述char ch[MAXLEN]; /*单词字符串*/int size; /*单词长度*/}Sequence;/*** 有序表类型定义*/typedef WordType ElemType;typedef struct NodeType{ //单词有序表结点定义ElemType data;struct NodeType *next;}NodeType,*LinkType;typedef struct{ //单词有序表定义LinkType head; /*有序表头指针*/LinkType tail; /*有序表尾指针*/int size; /*有序表结点个数*/}OrderList;* 记录一行中匹配成功单词在目标词汇表中的位置*/typedef struct{int eqelem[MAXNUM]; /*单词在目标词汇表中的位置*/int last; /*匹配成功单词的个数*/}EqelemList;/*** 文件测试相关的数据类型定义*/typedef struct Node{ //单词在文件中的位置int elem; /*被测单词在文件中的行号*/struct Node *next;/*指向下一个行号结点的指针*/}Node,*Link;typedef struct{ //单词统计分析记录结构定义WordType data; /*被测试的单词*/int count; /*在文件中出现的次数*/Link Next; /*记录出现的所有行号的脸表头指针*/}HeadNode;/*** 文本文件测试结果记录定义*/typedef HeadNode ResultType[MAXNUM];typedef int status;3、主要算法设计:/*---------------------与单词相关的函数---------------------*//*------------------------------------------------------------------*//* 定义新单词函数*//* 功能:把新单词放入堆中*//* 参数:WordType *nw--单词描述信息指针*//* Sequence cha--单词信息*//* 返回值:操作成功与否的状态信息*//* 0--操作失败,空间不足;1--操作成功*//*--------------------------------------------------------------*/status NewWord(WordType *nw,Sequence cha){int i,k;if(sp.freep+cha.size>=MAXSIZE){printf("Heap Full!\n");getchar();return 0;else{i=sp.freep;sp.freep=sp.freep+cha.size;for(k=0;k<cha.size;k++) sp.stores[i+k]=cha.ch[k];nw->stadr=i;nw->len=cha.size;return 1;}}/*------------------------------回到最初空间-------------------*/ void NewLength(OrderList rs){int m=0;LinkType p,q;p=rs.head->next;while(p){if(m<=p->data.stadr){m=p->data.stadr;q=p;}p=p->next;}sp.freep=m+q->data.len;}/*------------------------------------------------------------------*//* 复制单词信息函数*//* 功能:把一个单词信息复制到另一个变量中*//* 参数:WordType *nw--新单词描述信息指针*//* WordType *oldw--旧单词描述信息指针*//* 返回值:无*//*----------------------------------------------------------------*/ void CopyWord(WordType *nw,WordType oldw){nw->stadr=oldw.stadr;nw->len=oldw.len;}/*------------------------------------------------------------------*//* 单词比较函数*//* 功能:比较堆中两单词的大小*//* 参数:WordType wd1--第一个单词描述信息*//* WordType wd2--第二个单词描述信息*//* 返回值:-1--小于;0--等于;1--大于*//*--------------------------------------------------------------*/int WordCmp(WordType wd1,WordType wd2){int k,si,sj,m;si=wd1.stadr;sj=wd2.stadr;for(k=0;k<=wd1.len&&k<=wd2.len;k++){m=fabs((float)(sp.stores[si+k]-sp.stores[sj+k]));if(m!=0&&m!=32)break;if(k==wd1.len||k==wd2.len)break;}if(wd1.len==wd2.len){if(k==wd1.len)return 0;elseif(sp.stores[si+k]>sp.stores[sj+k])return 1;else return -1;}else if(wd1.len<wd2.len){if(k==wd1.len)return -1;elseif(sp.stores[si+k]>sp.stores[sj+k])return 1;else return -1;}else{if(k==wd2.len)return 1;elseif(sp.stores[si+k]>sp.stores[sj+k])return 1;else return -1;}}/*------------------------------------------------------------------*/ /* 打印单词函数*/ /* 功能:打印堆中一个单词*/ /* 参数:WordType wd--单词描述信息*/ /* 返回值:无*/ /*------------------------------------------------------------------*/ void PrintWord(WordType wd){int i;for(i=0;i<wd.len;i++) putchar(sp.stores[wd.stadr+i]);}/*-------------------与有序表相关的函数----------------------*//*-------------------------------------------------------------------*//* 结点生成函数*//* 功能:生成一个单词在堆中存储信息的结点*//* 参数:LinkType *p--生成的新结点指针*//* ElemType e--单词存储信息*//* 返回值:TRUE--成功;FALSE--失败*//*-----------------------------------------------------------------*/ status MakeNode(LinkType *p,ElemType e){*p=(LinkType)malloc(sizeof(NodeType));if(!(*p)) return FALSE;(*p)->data.stadr=e.stadr;(*p)->data.len=e.len;(*p)->next=NULL;return TRUE;}/*------------------------------------------------------------------------*/ /* 有序表初始化函数*/ /* 功能:申请头结点,初始化有序表*/ /* 参数:OrderList *L--有序表指针*/ /* 返回值:TRUE--初始化成功;FALSE--初始化失败*/ /*------------------------------------------------------------------------*/ status InitList(OrderList *L){ElemType wd;wd.len=0;if(MakeNode(&(L->head),wd)){L->tail=L->head;L->head->next=NULL;L->size=0;return TRUE;}else{L->head=NULL;return FALSE;}}/*------------------------------------------------------------------*/ /* 撤销有序表函数*/ /* 功能:释放有序表所有结点,撤销有序表*/ /* 参数:OrderList *L--有序表指针*/ /* 返回值:无*/ /*------------------------------------------------------------------*/ void DestroyList(OrderList *L){LinkType p,q;p=L->head;while(p){q=p;p=p->next;free(q);}L->head=L->tail=NULL;}/*-------------------------------------------------------------------*/ /* 有序表查找函数*/ /* 功能:确定给定单词e在有序表中的位置*/ /* 参数:OrderList L--有序表*/ /* ElemType e--给定要查找的数据e *//* LinkType *q--有序表结点指针*/ /* 查找成功,q指向具有e值的结点*//* 查找失败,q指向小于e的结点*//* 返回值:int型,1--查找成功;0--查找失败*//*-----------------------------------------------------------------*/ status LocateElem(OrderList L,ElemType e,LinkType *q) {LinkType pre,p;p=L.head->next;while(p){if(WordCmp(p->data,e)==0){*q=p;return TRUE;}if(WordCmp(p->data,e)==-1)*q=p;p=p->next;}return FALSE;}/*------------------------------------------------------------------*/ /* 有序表插入函数*//* 功能:在制定结点q后插入一个结点s *//* 参数:OrderList *L--有序表指针*//* LinkType q--指定结点指针*//* LinkType s--待查入结点指针*//* 返回值:无*//*---------------------------------------------------------------*/void InsertAfter(OrderList *L,LinkType q,LinkType s){if(L->head&&q&&s){s->next=q->next;q->next=s;if(L->tail==q) L->tail=s;L->size++;}}/*------------------------------------------------------------------------*/ /* 表匹配函数*/ /* 功能:把Lb表中匹配La表成功的元素放入s表*/ /* 参数:OrderList La--存放统计单词的有序表*/ /* OrderList Lb--存放待匹配单词的有序表*/ /* EqelemList *s--存放匹配成功单词信息表指针*/ /* 返回值:无*/ /*-------------------------------------------------------------------------*/ void ListCompare(OrderList La,OrderList Lb,EqelemList *s) {int pos,n;LinkType pa,pb;if(La.head&&Lb.head){pa=La.head->next;pb=Lb.head->next;s->last=pos=0;while(pa&&pb){n=WordCmp(pa->data,pb->data);if(n==0){s->eqelem[s->last++]=pos++;pa=pa->next;pb=pb->next;}else if(n==-1){pa=pa->next;pos++;}else pb=pb->next;}}}/*--------------------------------------------------------*//* 判表空函数*//* 功能:判断表L是否是空表*//* 参数:OrderList L--有序表*//* 返回值:0--非空表;1--空表*//*--------------------------------------------------------*/ status ListEmpty(OrderList * L){if(L->size==0) return TRUE;return FALSE;}int ListLength(OrderList* L){ /*返回判表长度*/ if(L->head ==L->tail) return 0;else return L->size ;}/*-----------与文本文件有关的函数-----------------------*/ /*---------------------------------------------------------------*/ /* 字符判断函数*/ /* 功能:判断文件中下一个字符是否为回车符*/ /* 参数:FILE *f--文件指针*/ /* 返回值:0--不是回车符;1--是回车符*/ /*---------------------------------------------------------------*/ int feoln(FILE *f){char cha;cha=fgetc(f);if(cha=='\n') return(TRUE);ungetc(cha,f);return FALSE;}/*---------------------------------------------------------------*/ /* 读取单词函数*/ /* 功能:从文件中读取一个单词*/ /* 参数:FILE *f--文件指针*/ /* Sequence *st--指向单词的指针*/ /* 返回值:无*/ /*----------------------------------------------------------------*/ void GetAWord(FILE *f,Sequence *st)char ch;int k=0;ch=fgetc(f);while(ch==' '){ch=fgetc(f);if(ch=='\n')break;}/*去掉空格和回车*/if(ch=='\n'){ungetc(ch,f);ch=' ';}/*最后一个为回车键,文件指针回指*/while(((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9'))&&!feof(f)) {st->ch[k]=ch;ch=fgetc(f);k++;}if(ch=='\n')ungetc(ch,f);st->size=k;}/*----------------------------------------------------------------*//* 读取文件当前行单词函数*//* 功能:提取文件指针所指行所有单词*//* 参数:FILE *f--文件指针*//* OrderList *ta--存放单词有序表的指针*//* 返回值:0--操作失败;1--操作成功*//*----------------------------------------------------------------*/status ExtractWord(FILE *f,OrderList *ta){int i;char lendc;Sequence str;WordType nwd;LinkType p,q;LinkType s;InitList(ta);p=ta->head;q=ta->head;for(i=0;!feof(f);i++){if(feoln(f))return(TRUE);GetAWord(f,&str);/*从文件中读出一个单词*/NewWord(&nwd,str);/*将单词放入堆存储空间*/MakeNode(&s,nwd);/*生成一个单词节点*/if(ta->head->next){while(p!=NULL&&WordCmp(p->data,s->data)==-1){q=p;p=p->next;}p=q;}InsertAfter(ta,p,s);p=ta->head->next;q=ta->head;}/*------------------------------------------------------------------*//* 文件单词匹配函数*//* 功能:统计指定单词在文件中出现的次数和位置*//* 参数:FILE *f--文件指针*//* OrderList pat--指定统计的单词有序表*//* ResultType rs--统计结果列表*//* 返回值:0--统计失败;1--统计成功*//*------------------------------------------------------------------*/status match(FILE *f,OrderList pat,ResultType rs){int i,k,linenum,failed,fsp;OrderList sa;EqelemList eqlist;Link p,q;if(!pat.head)return FALSE;linenum=1;while(!feof(f)){ExtractWord(f,&sa);ListCompare(pat,sa,&eqlist);i=0;if(st)while(i<st)/*计算出单词出现行号以及一行出现次数*/{p=(Link)malloc(sizeof(Node));p->next=rs[eqlist.eqelem[i]].Next;rs[eqlist.eqelem[i]].Next=p;p->elem=linenum;rs[eqlist.eqelem[i]].count++;i++;}/*内层while*/linenum++;/*行数加1*/DestroyList(&sa);NewLength(pat);}/*外层while*/fclose(f);return TRUE;}/*-------------------------------------------------------------------*//* 初始化文件函数*//* 功能:输入指定的文件名并打开文件*//* 参数:FILE **f--返回的文件指针*//* 返回值:0--初始化失败;1--初始化成功*/ /*---------------------------------------------------------------*/ status Initialization(FILE **fr){char FileName[30];printf("Input file name:");do{scanf("%s",FileName);}while(strlen(FileName)==0);*fr=fopen(FileName,"r");if(*fr){printf("file open!\n");return TRUE;}else{printf("file not open!\n");return FALSE;}}/*------------------------------------------------------------------*/ /* 输入统计的词集函数*/ /* 功能:输入待统计的词集并建立起数据结构*/ /* 参数:OrderList *pt--返回的词集有序表指针*/ /* 返回值:无*/ /*------------------------------------------------------------------*/ void InputWord(OrderList *pt){char cc;int i=0;Sequence ws;LinkType p,q,s;WordType nwd;InitList(pt);p=pt->head;q=pt->head;while((cc=getchar())){if(cc!=' '&&cc!='\n'){ws.ch[i]=cc;i++;}else{ws.size=i;NewWord(&nwd,ws);MakeNode(&s,nwd);if(pt->head->next){while(p!=NULL&&WordCmp(p->data,s->data)==-1){q=p;p=p->next;}p=q;}InsertAfter(pt,p,s);p=pt->head->next;q=pt->head;i=0;}if(cc=='\n')return;}}/*------------------------------------------------------------------*//* 初始化统计结果表函数*//* 功能:用待统计词集初始化统计结果表*//* 参数:ResultType rs--统计结果数组*//* OrderList pt--待统计的词集表*//* 返回值:无*//*-----------------------------------------------------------------*/void InitRList(ResultType rs,OrderList pat){int k;LinkType p;p=pat.head->next;for(k=0;k<pat.size;k++){CopyWord(&rs[k].data,p->data);rs[k].Next=NULL;rs[k].count=0;p=p->next;}}/*------------------------------------------------------------------*//* 输出统计结果函数*//* 功能:输出统计的结果*//* 参数:ResultType rs--统计结果数组*//* int n--待统计的词集个数*//* 返回值:无*//*-------------------------------------------------------------------*/void OutResult(ResultType rslist,int n){int i,j;Link p;for(i=0;i<n;i++){printf("The word ");PrintWord(rslist[i].data);printf(" appeared in the file %d times",rslist[i].count);if(rslist[i].count!=0){printf(" and on ");p=rslist[i].Next;for(j=0;j<rslist[i].count;j++)if(j<rslist[i].count-1){printf("%d,",p->elem);p=p->next;}else printf("%d\n",p->elem);}else printf("\n");}}/*------------------------------------------------------------------*//* 撤销统计结果数据空间函数*//* 功能:释放存放统计结果数据的动态存储空间*//* 参数:ResultType rs--统计结果数组*//* 返回值:无*//*------------------------------------------------------------------*/ void FreeResult(ResultType rs,int n){int i;Link p,q;for(i=0;i<n;i++)if(rs[i].Next!=NULL)break;if(rs[i].Next!=NULL)for(i=0;i<n;i++){p=rs[i].Next;while(p){q=p;p=p->next;free(q);}rs[i].Next=NULL;rs[i].count=0;}else return;}int main(){int flag=0;sp.freep=0; /*sp为全局变量*/FILE *fp=NULL;OrderList *pt;pt=(OrderList *)malloc(sizeof(OrderList));pt->head=NULL;ResultType rs;do{Initialization(&fp); /*输入文件名并打开文件*/printf("input search words\n");getchar();InputWord(pt); /*输入查询的单词*/if(fp&&!ListEmpty(pt)){InitRList(rs,*pt);if(match(fp,*pt,rs))OutResult(rs,ListLength(pt));elseDestroyList(pt);}printf("Do you want to have a seach again?(YES--1/NO--0)\n");scanf("%d",&flag);fflush(stdin);}while(flag);system("pause");return 0;}五、调试分析:1、在编程的过程中,对设计做了如下修改:1)考虑到堆空间可能设置不够大,以至可能引起数组出界的错误,因此将NewWord 改为status类型函数,返回堆空间分配成功与否的信息。