文字编辑.docx
《文字编辑.docx》由会员分享,可在线阅读,更多相关《文字编辑.docx(21页珍藏版)》请在冰豆网上搜索。
文字编辑
摘要
设计一个文字编辑程序,用来实现以下功能:
分别统计出其中英文字母和空格数及整篇文章总字数;统计某一字符串在文章中出现的次数,并输出该次数;删除某一子串,并将后面的字符前移;插入一子串,并输出插入子串后的文章。
用线性表实现存储。
关键词:
文字编辑、线性表、串
目录
1.问题描述1
2.需求分析1
3.概要设计1
3.1抽象数据类型定义1
3.2模块划分2
4.详细设计3
4.1函数定义3
4.2主要算法的描述4
5.测试分析7
6.课程设计的总结与体会8
参考文献9
附录(源程序清单)10
1.问题描述
输入一页文字,程序可以统计出文字、数字、空格的个数。
(1)分行输出用户输入的各行字符;
(2)分4行输出"全部字母数"、"数字个数"、"空格个数"、"文章总字数";
(3)输出删除某一字符串后的文章。
2.需求分析
(1)静态存储一页文章,每行最多不超过80个字符,共N行
(2)分别统计出其中英文字母数和空格数及整篇文章总字数;
(3)统计某一字符串在文章中出现的次数,并输出该次数;
(4)删除某一子串,并将后面的字符前移;
(5)插入一子串,并输出插入子串后的文章;
(6)存储结构使用线性表,分别用几个子函数实现相应的功能。
3.概要设计
3.1抽象数据类型定义
(1)定义最大行数为10
#defineLINK_INIT_SIZE10;
(2)定义全局变量,Num用来记录行号,C用来记录子串在主串中出现的总次数
intNUM,C,N;
(3)线性表的定义
typedefstruct_list
{
chars[80];
intlength;
struct_list*next;
struct_list*pre;
introw;
}linklist;
linklist*head;
(4)定义子函数Get(),用来输入文章
linklist*Get()
接收输入字符
ch=getchar();
(5)定义子函数out,用来输出文章
voidOut()。
3.2模块划分
本程序包括四个模块:
(1)主程序模块
intmain()
{
欢迎使用简易文本编辑器系统;
所输入要编译的文章为;
显示文章并且输出所有统计项目;
请输入要查找的字符串;
请输入要删除的子串;
删除子串后的文章为;
请输入要插入的子串;
请输入要插入的行;
请输入要插入的列;
插入子串后的文章;
再见;
错误选择,重新开始;
}
(2)线性表定义——实现线性表的定义
(3)输入函数——实现文章的输入
(4)输出函数——实现文章的输出
4.详细设计
4.1函数定义
(1)主函数运用switch语句来实现选择菜单,同时实现了各个结果的输出。
(2)线性表的定义运用了结构体:
typedefstruct_list//行表结构
{
chars[80];//记录一行字符
intlength;//记录一行字符长度
struct_list*next;//后继指针
struct_list*pre;//前趋指针
introw;//记录整篇文章的行数
}linklist;
linklist*head;//定义全局变量*head,文章首行头指针
(3)输入文章的函数
linklist*temp;
charch;
inti,j;
head->next=(linklist*)malloc(sizeof(linklist));//申请内存空间
head->pre=NULL;//首行头指针的前驱指针为空
temp=head->next;//首行指针
temp->pre=NULL;//首行指针的前驱指针也为空
temp->length=0;//没输入字符时文章长度为0
for(i=0;i<80;i++)
temp->s[i]='\0';//初始化为字符串结束标志,防止出现乱码
printf("请输入文章(#结束输入):
\n");
(4)输出文章的函数
t=head->next;
for(j=0;j<=NUM&&t!
=NULL;j++)
{
for(i=0;(i<80)&&(t->s[i])!
='#';i++)
{
printf("%c",t->s[i]);//输出整个文章
}
printf("\n");
t=t->next;//指向下一行
}
4.2主要算法的描述
(1)主函数如图4.2.1所示,实现了各个结果的输出。
图4.2.1
(2)子函数Get()如图4.2.2所示,实现文章的输入。
图4.2.2
(3)子函数Out()如图4.2.3所示,实现文章的输出。
图4.2.3
5.测试分析
文章输入如图5.1,输入一段文字。
图5.1
文章输出如图5.2,将前面输入的文章输出。
图5.2
6.课程设计的总结与体会
通过这次课程设计使我充分的理解了用线性表实现文字编辑的基本原理,知道了线性表链式存储的定义,以及链表的一些基本操作算法的描述,同时也学会一些简单文字编辑的程序。
虽然此次的程序我没能全部都参与,而只是完成了其中的几个部分,但是我的能力还是得到了提升。
当然,我完成的那些部分还不是很完备,但是总体还是一个比较能体现数据结构知识点能力的程序了,当然只是相对于我这个初学者来说。
在刚开始编程的时候,我感到很茫然,几天下来我没有半点头绪,于是我开始有了一个错误的想法,在网上下载一个程序浑水摸鱼,或者找朋友帮忙完成。
但是在成老师以及同组成员的热情帮助和讨论下,我查找资料,参考教材,花费俩天将程序编写了出来,在经过成老师的认真批改,源程序诞生了。
之后,我一步一步将其他剩余的部分也完成了。
看着自己的成果,真的很高兴,很有成就感。
在此我非常要感谢的是我的指导老师李首洪老师,感谢老师的细心认真的辅导,让我对数据结构这门课程有了更新的认识和理解。
这次课程设计能够顺利的完成,当然有我个人的努力,但同时也离不开指导老师的答疑解惑,以及同组成员的帮助与合作。
在此我再次向成老师以及其他两位组员表示诚挚感谢。
参考文献
[1]严蔚敏,吴伟民.数据结构(C语言版)[M].北京:
清华大学出版社,2002
[2]刘振鹏,张晓莉,郝杰.数据结构[M].北京:
中国铁道出版社,2003
[3]李春葆.数据结构习题与解析(C语言篇)[M].北京:
清华大学出版社,2000
附录(源程序清单)
源程序
#include
#include
#include
#include
usingnamespacestd;
#defineLINK_INIT_SIZE10//定义最大行数为10
intNUM,C,N;//定义全局变量,Num用来记录行号,C用来记录子串在主串中出现的总次数
typedefstruct_list//行表结构
{
chars[80];//记录一行字符
intlength;//记录一行字符长度
struct_list*next;//后继指针
struct_list*pre;//前趋指针
introw;//记录整篇文章的行数
}linklist;
linklist*head;//定义全局变量*head,文章首行头指针
linklist*Get()//子函数Get(),用来输入文章
{
linklist*temp;
charch;
inti,j;
head->next=(linklist*)malloc(sizeof(linklist));//申请内存空间
head->pre=NULL;//首行头指针的前驱指针为空
temp=head->next;//首行指针
temp->pre=NULL;//首行指针的前驱指针也为空
temp->length=0;//没输入字符时文章长度为0
for(i=0;i<80;i++)
temp->s[i]='\0';//初始化为字符串结束标志,防止出现乱码
printf("请输入文章(#结束输入):
\n");
for(j=0;j{
for(i=0;i<80;i++)//控制一行
{
ch=getchar();//接收输入字符
temp->s[i]=ch;//给temp指向的行赋值
temp->length++;//行中字符长度加1
if(ch=='#'){NUM=j;break;}//文章结束时,Num来记录整个文章的行数
}
if(ch=='#'){temp->length=i;temp->next=NULL;break;}//结束时,最后一行长度是i,temp是最后一行
temp->next=(linklist*)malloc(sizeof(linklist));//输入字符数大于80,重新分配空间建立下一行
temp->next->pre=temp;//给temp的前驱指针赋值
temp=temp->next;//temp指向当前行
for(i=0;i<80;i++)//将下一行初始化为字符串结束标志,防止出现乱码
temp->s[i]='\0';
}
temp->row=NUM+1;//记录整个文章的行数
returntemp;//返回指向最后一行指针
}
voidOut()//子函数out,用来输出文章
{
inti,j;
linklist*t;
t=head->next;//t指向文章首行
for(j=0;j<=NUM&&t!
=NULL;j++)
{
for(i=0;(i<80)&&(t->s[i])!
='#';i++)
{
printf("%c",t->s[i]);//输出整个文章
}
printf("\n");
t=t->next;//指向下一行
}
}
voidWorldNum()//子函数WorleNum,用来统计字符数
{
linklist*temp;
charch;
inti,j,Eworld=0,num=0,space=0,world=0,build=0;
temp=head;
for(j=0;j<=NUM;j++)
{
temp=temp->next;//t指向文章首行
for(i=0;(i<80)&&(temp->s[i]!
='#');i++)
{
ch=temp->s[i];
if((ch>='a')&&(ch<='z')||(ch>='A')&&(ch<='Z'))Eworld++;//字母数加1
elseif((ch>='0')&&(ch<='9'))num++;//数字数加1
elseif(ch=='')space++;//空格数加1
elseif(ch==33||ch==34||ch==39||ch==44||ch==46||ch==58||ch==59||ch==63){build++;}//标点符号数加1
}
world=Eworld+num;//文章总字数等于字母个数加数字个数
}
printf("统计后得:
\n");
printf("全部字母数:
%d\n数字个数:
%d\n空格个数:
%d\n文章总字数:
%d\n\n",Eworld,num,space,world);
}
voidCompare(char*ss,linklist*temp)//子函数Compare,用来查找子串出现的总次数和每次出现的位置
{
charaa[20];
linklist*str=(linklist*)malloc(sizeof(linklist));
inti,j,k=0,sum=0;
intl=1;
temp=head->next;
strcpy(aa,ss);
for(i=0;i<=NUM;i++)
{
for(j=0;j<80;j++)
{
if((temp->s[j])==aa[k])k++;//找第一个相同字母
elseif(aa[k]!
='\0'){j=j-k;k=0;}//从主串第j-k个位置重新查找
if(aa[k]=='\0')
{sum++;//出现次数加1
j=j-k+1;//j记录下该字符串出现的位置
printf("第%d次出现在第%d行第%d列\n",l,i+1,j+1);
l++;
k=0;
continue;}
}
temp=temp->next;//指向下一行
}
printf("字符串总共出现次数为:
%d\n\n",sum);
C=sum;//全局变量C用来记录子串在主串中出现的总次数
N=i*80+j;//记录字符串出现的行号
}
voidAftdel(char*ss)//子函数Aftdel,用来删除子串
{charaa[20];
linklist*temp,*term;
inti,j,k,m,y,num;
strcpy(aa,ss);
for(y=0;y{
num=80;
k=0,m=0;
temp=head;
for(i=0;i<=NUM;i++)
{
term=temp;
temp=temp->next;
for(j=0;j<80;j++)
{
if((temp->s[j])==aa[k])k++;
elseif(aa[k]!
='\0'){j=j-k;k=0;}
if(aa[k]=='\0'){num=j;break;}
}
if(num<80)break;
}
for(;i<=NUM;i++)
{
for(;j<80;j++)
{
if(j+1{
term->s[80-k+num]=temp->s[j+1];//删除的字符串不在最后一行,将下一行的字符(由temp指向)前移到前行
}
elsetemp->s[j-k+1]=temp->s[j+1];//当要删除的字符串在最后一行只要将最后一行的字符前移。
}
term=temp;//指针后移
temp=temp->next;j=0;
}
}
}
linklist*Insert(linklist*temp,char*ss,inti)
{linklist*cur;
intn=strlen(ss);
intm;
intinsertRow=i/80+1;
introw=temp->row;
intj;
if(insertRow==row){//插入的位置在最后一行
for(m=temp->length-1;m>=(i%80)&&n>0;m--)
temp->s[m+n]=temp->s[m];//最后一行插入位置后面的字符全部向后移n位
for(m=(i%80),j=0;mtemp->s[m]=ss[j];//将要插入的字符串赋值到插入的位置。
}
}else{//插入的位置不在最后一行
into=0;
for(intp=insertRow;pif(p==insertRow)
o=0;
else
o=n;
for(m=temp->length-1-o;m>=0&&n>0;m--)
temp->s[m+n]=temp->s[m];//将最后一行整体后移n位
cur=temp;//cur指向当前行
temp=temp->pre;//temp指向前一行
temp->length=80;
for(m=temp->length-n,j=0;mlength;m++,j++)
cur->s[j]=temp->s[m];//将前一行后n个字符移到下一行前n个字符
}
for(m=temp->length-n-1;m>=(i%80);m--)
temp->s[m+n]=temp->s[m];//插入行插入位置后的字符后移n位
for(m=(i%80),j=0;m<(i%80)+n;m++,j++)
temp->s[m]=ss[j];//要插入的字符赋值到插入位置
}
returntemp;
}
intmain()
{
intb,p,q;boolstop=0;chary;inti;
charss[20];chara[10];
printf("***************************\n");
printf("欢迎使用简易文本编辑器系统\n");
printf("***************************\n");
head=(linklist*)malloc(sizeof(linklist));
linklist*temp=Get();
do
{printf("***************************\n");
printf("1显示文章并且输出所有统计项目\n");
printf("2查找字符串\n");
printf("3删除子串\n");
printf("4插入子串\n");
printf("5结束程序\n");
printf("***************************\n");
printf("请选择:
");
cin>>a;
if(strcmp(a,"1")==0)
b=1;
elseif(strcmp(a,"2")==0)
b=2;
elseif(strcmp(a,"3")==0)
b=3;
elseif(strcmp(a,"4")==0)
b=4;
elseif(strcmp(a,"5")==0)
b=5;
elseb=6;
switch(b)
{
case1:
printf("所输入要编译的文章为:
\n");
Out();
WorldNum();
printf("继续?
请选择:
");
getchar();
if(getchar()=='n')
stop=1;
break;
case2:
printf("请输入要查找的字符串:
\n");
getchar();
gets(ss);
Compare(ss,temp);
printf("继续?
请选择:
");
scanf("%s",&y);
if(y=='n')
stop=1;
break;
case3:
printf("请输入要删除的子串:
\n");
scanf("%s",ss);
Compare(ss,temp);
Aftdel(ss);
printf("删除子串后的文章为:
\n");
Out();
printf("继续?
请选择:
");
getchar();
if(getchar()=='n')
stop=1;
break;
case4:
printf("请输入要插入的子串:
\n");
scanf("%s",ss);
printf("请输入要插入的行:
\n");
scanf("%d",&p);
printf("请输入要插入的列:
\n");
scanf("%d",&q);
i=(p-1)*80+q;
Insert(temp,ss,i);
printf("插入子串后的文章为:
\n");
Out();
printf("继续?
请选择:
");
getchar();
if(getchar()=='n')
stop=1;
break;
case5:
stop=1;printf("\t再见!
\n");break;
case6:
printf("错误选择,重新开始\n");
break;
}
}while(!
stop);
}
|