文章编辑 数据结构课程设计.docx
《文章编辑 数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《文章编辑 数据结构课程设计.docx(23页珍藏版)》请在冰豆网上搜索。
文章编辑数据结构课程设计
课题名称
文章编辑
Ⅰ、题目的目的和要求:
设计中要求综合运用所学知识,上机解决一些与实际应用结合紧密的、规模较大的问题。
通过分析、设计、编码、调试等各环节的训练,使学生深刻理解、牢固掌握数据结构和算法设计技术,掌握分析、解决实际问题的能力。
通过这次设计,要求在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
Ⅱ、设计进度及完成情况
日期
内容
7.2-7.4
熟悉设计任务,查阅有关文献资料,确定所采用的数据结构,初步制定解决问题的方法,完成课程设计说明书内容1-3部分。
7.5~7.10
选择合适的存储结构,明确解决问题的算法,上机编写并调试源程序。
7.11~7.12
整体调试程序并记录调试中的问题,完成课程设计说明书第4-7部分。
7.13
演示设计成果,考核成绩。
整理课程设计说明书,上午11时,由学习委员交课程设计说明书(计算机科学系9#213或直接交给指导教师)
Ⅲ、主要参考文献及资料
[1]严蔚敏、吴伟民主编,《数据结构》(C语言版),清华大学出版社,2002。
[2]殷人昆等著,《数据结构》(C++版),清华大学出版社,2001。
[3]金远平著,《数据结构》(C++描述),清华大学出版社,2005。
[4]许卓群等著,《数据结构与算法》,高等教育出版社,2004。
[5]FrankM.Carrano等著,《数据结构与C++高级教程》,清华大学出版社,2004。
[6]严蔚敏、吴伟民著,《数据结构习题集》(C语言版),清华大学出版社。
Ⅳ、成绩评定:
设计成绩:
(教师填写)
指导老师:
(签字)
二○○七年七月二十日
第一章概述.............................................1
第二章系统分析.........................................2
第三章系统设计.........................................3
第四章程序设计流程图或N-S图...........................4
第五章源程序清单.......................................6
第六章调试过程中的问题及系统测试情况...................13
第七章结束语...........................................22
第一章概述
一.本课程设计意义
课程设计是实践性教学中的一个重要环节,它以某一课程为基础,可以涉及和课程相关的各个方面,是一门独立于课程之外的特殊课程。
课程设计是让同学们对所学的课程更全面的学习和应用,理解和掌握课程的相关知识。
《数据结构》是一门重要的专业基础课,是计算机理论和应用的核心基础课程。
数据结构课程设计,要求学生在数据结构的逻辑特性和物理表示、数据结构的选择和应用、算法的设计及其实现等方面,加深对课程基本内容的理解。
同时,在程序设计方法以及上机操作等基本技能和科学作风方面受到比较系统和严格的训练。
二.本课程设计的目的和任务
1.提高对数据逻辑结构的特点以及存储表示方式的认识,培养在具体应用中选择合适的数据结构和存储结构的能力。
2.熟悉软件开发的基本过程,初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等阶段基本任务和技能方法。
3.培养自己的算法设计和算法分析能力,提高综合运用所学的理论知识和方法独立分析和解决问题的能力。
4.训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的工作方法、作风和相互合作的精神。
5.综合运用链表的查找、插入和删除,理论结合实际,将其运用到文章编辑这一实验中。
使这些知识得到进一步巩固、加深和拓展。
利用模块的思想,模块之间用指针连接,减少了不必要的麻烦。
巩固加深指针的用途,理解模块的优点。
加深对链表的理解,全面认识链表操作的字符串的模式匹配操作。
第二章系统分析
本实验所要实现的功能:
输入一页文字,程序可以统计出文字、数字、空格的个数。
静态存储一页文章,每行最多不超过80个字符,共N行;
要求:
(1)分别统计出其中英文字母数和空格数及整篇文章总字数;
(2)统计某一字符串在文章中出现的次数,并输出该次数;
(3)删除某一子串,并将后面的字符前移。
存储结构使用线性表,分别用几个子函数实现相应的功能;
输入数据的形式和范围:
可以输入大写、小写的英文字母、任何数字及标点符号。
输出形式:
(1)分行输出用户输入的各行字符;
(2)分4行输出"全部字母数"、"数字个数"、"空格个数"和"文章总字数"
输出删除某一字符串后的文章;
用链表存放数据非常灵活,只要内存足够大,对链表可以做任意扩充和修改。
主要的手段为链表的遍历。
定义一个头指针head,每个结点的数据域存放数据本身,指针域存放下一个结点地址,所以,我们只要知道head,就可以遍历整个链表,找到我们所需要的字符(串),进行相应的操作。
第三章系统设计
一.输入模块
存储结构:
采用单链表结构存储文章,每个结点存储一行,每行最长不超过80个字符。
结构定义:
typedefstructline{
char*data;//字符串指针需要时动态分配内存
structline*next;
}LINE;
算法描述:
用gets函数接收输入,每遇到一个回车换行就新建一个结点,将当前行存入其data域。
当发现输入为^E时,在Data的最后加上字符串结束标志,并置当前结点的Next指针域为NULL。
二.统计模块
统计模块包括统计全部字母数,统计数字个数,统计空格个数,以及统计文章总字数,这四个部分的实现算法大体相同,四者的关系是:
全部字母数+数字个数+空格个数=文章总字数,也就是说可以在统计出其中三者的前提下计算出第四个的数量。
另外一个重要的统计功能是统计某一字符串在整篇文章中出现的次数,这个需要用到串的模式匹配算法来实现。
三.删除模块
删除模块的算法思想类同统计字符串的算法思想,由于采用了链表的存储结构,使得删除算法的时间复杂度大大减少。
voidDel_String(LINE*&head,char*sch){//删除指定的字符串
LINE*p=head;
do
{
while(strstr(p->data,sch)!
=NULL)del_string_word(p->data,sch);
}while((p=p->next)!
=NULL);//遍历链表
第四章程序设计流程图
根据题目与上述分析,可得主程序设计流程图如下所示:
图1-1
文章输入、浏览、统计串、统计及删除的详细流程如图1—2所示:
回车回车回车
Ctrl+E
回车
回车
回车
回车
(接上页图)
回车回车
回车
回车回车
回车
回车
图1-2
第五章源程序清单
#include
#include
#include
#include
#include
typedefstructline{
char*data;//字符串指针需要时动态分配内存
structline*next;
}LINE;
voidCreateTXT(LINE*&head);//创建一张列表,同时向里面输入文本数据
intCount_Space(LINE*&head);//统计空格数
intCount_ZM(LINE*&head);//统计字母数
intCount_All_Word(LINE*&head);//统计文章的总字数
intFind_Word(LINE*&head,char*sch);//统计sch在文章中出现的次数
intCount_Num(LINE*&head);//统计数字数
voidDel_String(LINE*&head,char*sch);//删除指定的字符串
voidOutPutTxt(LINE*&head);//向屏幕输出文章
voidTj(LINE*&head);//统计
intread_text(LINE*&head);
intfree_link(LINE*&head);
intfree_link(LINE*&head)
{
LINE*p=head;
do
{p->data=NULL;
free(p->data);
}
while((p=p->next)!
=NULL);
head->next=NULL;
return0;
}
voidsetcolor(unsignedshortcolor)
{
HANDLEhCon=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hCon,color);
}
voidCreateTXT(LINE*&head){
LINE*p=newLINE;//首先为链表建立一个附加表头结点
head=p;//将p付给表头指针
chartmp[80];
while
(1)
{
gets(tmp);//输入字符串!
使用C的输入函数
if(tmp[0]==5)break;//如果发现输入^E,则退出输入
p->data=newchar[strlen(tmp)+1];//为结点分配空间
strcpy(p->data,tmp);
if(tmp[strlen(tmp)-1]==5){//除去最后一个控制符^E
p->data[strlen(tmp)-1]='\0';
break;
}
}
p->next=NULL;//是最后的一个指针为空。
head=head->next;
}
intCount_Space(LINE*&head){//统计空格数
LINE*p=head;
intasc_space=32;//空格的ASCIC码值
intcount=0;
do
{
intLen=strlen(p->data);//计算当前data里的数据元素的个数
for(inti=0;iif(p->data[i]==asc_space)count++;//计算空格数
}
while((p=p->next)!
=NULL);//遍历链表
returncount;
}
intCount_Num(LINE*&head){//统计数字数
LINE*p=head;
intcount=0;
do
{
intLen=strlen(p->data);//计算当前data里的数据元素的个数
for(inti=0;iif(p->data[i]>=48&&p->data[i]<=57)count++;//计算数字数
}
while((p=p->next)!
=NULL);//遍历链表
returncount;
}
intCount_ZM(LINE*&head){//统计字母数
intcount=Count_All_Word(head);//总的字符数,包含空格
intspace_count=Count_Space(head);//空格数
intnum_count=Count_Num(head);//数字数
returncount-space_count-num_count;//返回文章的字母总数
}
intCount_All_Word(LINE*&head){//统计文章的总字数
LINE*p=head;//保存链表的首地址
intcount=0;//总字母数
do
{count+=strlen(p->data);}//计算当前行内的字符数
while((p=p->next)!
=NULL);//遍历链表
returncount;
}
intFind_Word(LINE*&head,char*sch){//统计sch在文章中出现的次数
LINE*p=head;
intcount=0;
//inth=0;
intlen1=0;//保存当前行的总字符数
intlen2=strlen(sch);//待统计字符串的长度
inti,j,k;
do
{
len1=strlen(p->data);//当前行的字符数
for(i=0;i{
if(p->data[i]==sch[0])
{
k=0;
for(j=0;j<=len2-1;j++)
if(p->data[i+j]==sch[j])k=k+1;
if(k==len2){count++;i=i+k-1;}
}
}
}
while((p=p->next)!
=NULL);//遍历链表
returncount;
}
voiddel_string_word(char*s,char*sch)
{
//*s为输入的字符串
//*sch为将要删除的字符
char*p=strstr(s,sch);//查询结果
chartmp[80];
intlen=strlen(s);
inti=len-strlen(p);
intj=i+strlen(sch);
intcount=0;
for(intk=0;k
for(intkk=j;kktmp[count]='\0';
strcpy(s,tmp);//返回新的字符串
}
voidDel_String(LINE*&head,char*sch){//删除指定的字符串
LINE*p=head;
do
{
while(strstr(p->data,sch)!
=NULL)del_string_word(p->data,sch);
}while((p=p->next)!
=NULL);//遍历链表
}
voidOutPutTxt(LINE*&head){//向屏幕输出文章
LINE*p=head;
do
{cout<data<}while((p=p->next)!
=NULL);//遍历链表
}
voidTj(LINE*&head){//统计
cout<<"文章统计信息结果如下:
"<cout<<"英文字母数:
"<cout<<"空格数:
"<cout<<"文章中共出现数字:
"<cout<<"统计文章的总字数:
"<}
voidmain()
{
setcolor(10);
LINE*head;
intopt;
cout<<"\n***************************************请选择操作**************************"<cout<<"1、新建";
cout<<"2、浏览";
cout<<"3、统计";
cout<<"4、串统计";
cout<<"5、删除";
cout<<"6、退出"<cin>>opt;
if(opt!
=1)
{cout<<"第一次请务必选择第1项,以输入文本以便操作"<opt=0;
}
else
{
//intn;inti;ElemTypee;
while(opt!
=6){
//
switch(opt){
case0:
{
cout<<"\n***************************************请选择操作**************************"<cout<<"1、新建";
cout<<"2、浏览";
cout<<"3、统计";
cout<<"4、串统计";
cout<<"5、删除";
cout<<"6、退出"<cin>>opt;
if(opt!
=1&&opt!
=2&&opt!
=3&&opt!
=4&&opt!
=5&&opt!
=6)
{cout<<"error!
不可识别选项!
"<break;}
case1:
{cout<<"--------新建文本---------------"<cout<<"请输入文本,每行最多输入80字符!
(结束请按Ctrl+E)"<setcolor(14);CreateTXT(head);setcolor(10);
cout<cout<<"按回车调出主菜单……"<getchar();
opt=0;break;}
case2:
{cout<<"--------浏览输入文本------------"<setcolor(14);OutPutTxt(head);setcolor(10);cout<cout<<"按回车调出主菜单……"<getchar();opt=0;break;}
case3:
{cout<<"-----------文本统计-------------"<setcolor(14);Tj(head);setcolor(10);
cout<cout<<"按回车调出主菜单……"<getchar();opt=0;break;}
case4:
{cout<<"----请输入要统计的字符串-----"<setcolor(14);
charsch[20];
gets(sch);
cout<cout<"<setcolor(10);
cout<<"-------------------------------"<cout<<"按回车调出主菜单……"<getchar();opt=0;break;}
case5:
{cout<<"------字符串删除------------"<setcolor(14);
cout<<"请输入要删除的某一字符串:
"<chartmp_sch[20];
//cin>>tmp_sch;
gets(tmp_sch);
Del_String(head,tmp_sch);//删除指定字符
cout<<"--------字符串"<OutPutTxt(head);//向屏幕输出文章
setcolor(10);
cout<cout<<"按回车调出主菜单……"<getchar();opt=0;break;}
case6:
exit(0);
default:
{
cout<<"请输入1~6之间的数字!
"<cout<<"按回车调出主菜单……"<getchar();opt=0;break;}
}//endofswitch
free_link(head);//释放链表空间
}//endofwhile
}//endofelse
}
第六章调试过程的系统测试情况及问题
一.测试情况
程序运行,首先显示选择菜单,如图示:
选择1,输入文章,界面运行结果如下:
按回车,调出开始菜单,输入2,选择浏览,可以原样显示出刚才输入的文本:
回车后输入3,可以看到文章统计信息结果:
根据页面提示,回车
统计字符串模块,输入要统计的字符串,可以查找出该字符串在文章中出现过的次数。
运行情况如下图示:
根据页面提示,回车
删除模块,输入要删除的字符串,执行删除后可以显示删除后的文本。
界面如下:
根据页面提示,回车:
退出页面,执行后的结果如下:
二.问题
1.主流程进入死循环。
.
解决方案:
每个循环都加break,每跳出一个模块,opt重新赋值为0。
2输入多个变量,需要空格间隔时,程序只读空格前的变量
解决方案:
输.入函数用get()函数,形式为:
get(tmp),即可解决着个问题。
3.不识别自定义函数。
解决方案:
函数定义前要函数声明,若不声明,则调用函数必须在函数定义之后,否则不识别。
4,程序结束之后,链表仍占空间。
解决方案:
在建立链表是所申请的内存空间在程序结束之前用free_link(LINE*&head)函数释放,即删除链表中的全部结点,且将链表头指针置为空。
三.注意事项:
(1)opt代表选项(共六个,多于六个显示“不可识别选项”)。
(2)建立文章,用链表存储,p=p->next=newLINE,即文章的每一行存储在一个结点中。
(3)Ctrl+E为结束标志。
(4)了解常用ASⅡ码。
第七章结束语
本实验采用链式顺序表结构实现了文章编辑的基本功能,实验过程中遇到了很多或大或小的问题,在这些问题的解决过程中,加深了对链表的理解,使我对链表操作的字符串的模式匹配有了更深更全面的认识。
本实验提高了我对数据逻辑结构的特点和存储表示方式的认识,培养了我在具体应用中选择合适的数据结构和存储结构的能力。
通过该实验,使我熟悉了软件开发的基本过程,初步掌握了软件开发过程