简易文本编辑器.docx
《简易文本编辑器.docx》由会员分享,可在线阅读,更多相关《简易文本编辑器.docx(37页珍藏版)》请在冰豆网上搜索。
简易文本编辑器
软件综合课程设计
简易文本编辑器
猴子吃桃子问题
二〇一四年六月
猴子吃桃子问题
1.问题陈述
有一群猴子摘了一堆桃子,他们每天都吃当前桃子的一半且再多吃一个,到了第10天就只余下一个桃子。
用多种方法实现求出原来这群猴子共摘了多少个桃子。
要求:
1)采用数组数据结构实现上述求解
2)采用链数据结构实现上述求解
3)采用递归实现上述求解
如果用数组结构解决这个问题,把猴子吃桃的天数倒过来看的话,以天数作为数组的下标i,剩下桃子的个数a[i]的递推公式为a[i]=(a[i-1]+1)*2。
a[i]实际代表了倒数第i天剩下的桃子数。
所以可以求得此数组的通项公式为a[i]=3*2e(i-1)-2(i>=2)。
如果用链结构解决这个问题,建立一个链表,根据每天桃子数与后一天桃子数的关系n=2*n+2,依次将每天的桃子数存进链表中,最后输出第一天的桃子数。
首先是建立一个空链表,产生一个头结点,且将头结点的地址赋给L。
然后把每天的桃子数从链表的第一个结点插入链表。
最后第一天的桃子数被最后一个插入链表,成为链表中第一个值,将其赋给e,最后只要输出e即得到第一天的桃子数。
如果用递归结构解决这个问题,要求利用他们每天都吃当前桃子的一半且再多吃一个这一特点,设计一个递归算法。
2.程序代码
#include
#include
#include"iostream"
#include"stdlib.h"
#defineTRUE1
#defineFALSE0
#defineERROR0
#defineOVERFLOW0
#defineOK1
#defineNULL0
typedefintStatus;
typedefintElemType;
structLNode
{
ElemTypedata;
LNode*next;
};
typedefLNode*LinkList;
voidInitList(LinkList&L)//构造一个空链链表
{
L=(LinkList)malloc(sizeof(LNode));//产生头结点,并使L指向此头结点
if(!
L)exit(OVERFLOW);
L->next=NULL;
}
StatusGetElem(LinkListL,inti,ElemType&e)//当第i个元素存在的时,将其值赋给e
{
intj=1;//计数器初值为0
LinkListp=L->next;//p指向第一个结点
while(p&&j
{
j++;
p=p->next;
}
if(!
p||j>i)
returnERROR;
e=p->data;
returnOK;
}
StatusListInsert(LinkListL,inti,ElemTypee)//在第i个位置之前插入元素e
{
intj=0;//计数器初值为0
LinkLists,p=L;//p指向头结点
while(p&&j{
j++;
p=p->next;
}
if(!
p||j>i-1)return0;
s=(LinkList)malloc(sizeof(LNode));//生成新的结点
s->data=e;
s->next=p->next;//新结点指向原第i个结点
p->next=s;//原第i-1个结点指向新结点
return1;
}
voidshuju()
{
intda,tao[11];//定义数组和下标
tao[0]=0;//tao[0]赋值为0
tao[1]=1;//倒数第一天的桃子数为1
for(da=2;da<=10;da++)
tao[da]=3*pow(2,da-1)-2;//给数组的赋值
printf("最初的桃子数为%d\n",tao[10]);//输出最初的桃子数
}
intsum_fan(intn,inti)//子函数sum_fun,参数n和i接受主函数的参数x和day
{
if(i>0)
{
n=sum_fan((n+1)*2,--i);//每一次都用((n+1)*2)的值去调用子函数本身
}
returnn;//返回结果
}
voidmain()
{
intsum;
intday=9;//实现函数调用的次数
intx=1;//最后一天还剩得一个桃子
intt;
LinkListL;
inti,e,n;
InitList(L);//初始化链表
do{
printf("\n");
printf("********************\n");
printf("1、数组数据结构实现\n");
printf("2、链数据结构实现\n");
printf("3、递归实现\n");
printf("4、退出\n");
printf("********************\n");
printf("请选择(1~4):
");
scanf("%d",&t);
if((t>4)&&(t<1))
{
printf("对不起,无此功能,请输入正确的功能序号!
\n");
}
//getchar();
else
switch(t)
{
case2:
sum=sum_fan(x,day);//调用子函数sum_fan,并把返回得结果赋给sum
printf("%d",sum);
break;
case1:
shuju();break;
case3:
for(i=1,n=1;i<=10;i++)
{
n=2*n+2;//将每一天的桃子数赋值给n
ListInsert(L,1,n);//将n的值输入链表
}
GetElem(L,2,e);
printf("最初的桃子数为%d",e);//输出桃子的数目break;
}
if(t==4)break;
}
while
(1);}
3.运行结果
(1)数组数据结构实现结果,如图3-1所示:
图3-1
(2)链数据结构实现结果,如图3-2所示:
图3-2
(3)递归实现结果,如图3-3所示:
图3-3
简易文本编辑器
1.问题陈述
(1)设计内容和要求
1)具有图形菜单界面;
2)查找,替换(等长,不等长),插入(插串,文本块的插入)、块移动(行块,列块移动),删除
3)可正确存盘、取盘;
4)正确显示总行数。
2.需求分析
要设计一简易的文本编辑器,要求有图形菜单界面,也就是菜单选择的界面,要实现的功能有对文本进行存盘,取盘,在某一个盘中新建一个TXT的文件,在里面输入内容,对这个文件进行取盘,显示出文本内容,并在显示的时候显示行数,具有对文本进行查找、替换、插入、移动、删除等功能。
为实现数据的有序存储,该编辑器应该用顺序表来存储输入的信息。
顺序表是数据结构中线性表的一种,它是用一块地址连续的存储空间依次存储线性表的元素。
其特点为:
在顺序表上逻辑关系相邻的两个元素在物理位置上也相邻;在顺序表上可以随即存取表中的元素。
在编辑器的主界面中应有如下提示信息:
显示当前文本信息:
从文件中读出文本,在某一个盘中创建一个文本文件,所以要读出来,显示到显示器上,并统计出行数。
查找文本信息:
因为在下面做插入,删除,移动之类的都需用到查找,在查找的时候,也要调用一个字符匹配模式的程序,来判断查找的内容是否符合所要查找的内容。
删除文本信息:
首先在数组中查找要删除的信息,查找的时候调用匹配模式的子函数,如果找到该信息,提示是否确认删除该信息,通过确认来删除信息,如果未找到要删除的信息,提示未找到该信息;
插入文本信息:
首先调用字符匹配模式的子函数找到插入点,如果找到该插入点,提示输入插入信息,确认插入信息后,选择是否在这个位置插入,如果是的话执行插入,不是的话再往下查找下一个插入点。
替换文本信息:
首先在数组中查找要被替换的信息,如果找到该信息,提示输入要替换的信息内容,否则提示未找到要被替换的信息;
保存文本信息:
在这里使用文件写入读出的功能,把你修改完的内容保存到你所建立的文本中。
显示文本内容:
读出文件中的所有字符,显示到显示器上。
退出
3.概要设计
(1)所用到的函数有:
文件的打开:
voidopen(chartext[]);
文件的保存:
voidsave(chartext[]);
查找文本:
voidsearch(chartext[],intl);
字符的匹配:
intstrindex(chartext[],chart[],inti2,intl);
文本的输出:
voidoutput(chartext[]);
删除文本:
voidDelete(charp[],intl);
插入文本:
voidinsert(chartext[],intl);
替换文本:
voidReplace(intstatus);
(2)程序流程图:
程序分为了多个子函数,程序中的子模块的分类图,总共分为了六个主要的模块,分别是否打开,保存,查找,删除,插入,替换,这六个模块的选择,在菜单的子程序中进行,在main函数中进入菜单选择,进行功能的选择。
流程如图3-1所示:
主函数
菜单
打开文本
保存文本
查找文本
删除文本
插入文本
替换文本
图3-1
在程序中,查找,删除,插入,替换的子程序都需要调用到intstrindex(chartext[],chart[],inti2,intl);的子程序,据此画出了程序的执行的流程图,程序的执行的简单的流程图,如图3-2所示:
图3-2
4.详细设计
(1)对于文本内容的处理,查找部分仍是使用循环对已存储的文章进行匹配,判断需要查找的字符或者字符串是否与文章中某部分内容相同,在程序的执行中,先是进入的主函数,在主函数中调用了菜单函数,进行功能的选择,各个模块分为多个函数来实现。
在程序中,设置了几个全局变量,来记录文本的内容等信息:
chartext[MAX]="";//文本编辑域
charname[20]="";//文件保存的位置
intstatus=0;//显示是否保存过的状态
intntext;//文本编辑的位置
(2)字符匹配
在这个程序中要特别注意的是字符的匹配,因为查找、插入、替换都需要用到这一步设计。
在这里我设计了一个子模块来实现匹配:
intstrindex(chartext[],chart[],inti2,intl)//查找要操作的数据的位置(模式匹配)
{
inti1=l,j=0;
while(i1{if(text[i1]==t[j])//继续匹配下一个字符
{j++;
i1++;}//主串和子串依次匹配下一个字符
else//主串、子串指针回溯重新开始下一次匹配
{i1=i1-j+1;//主串从下一个位置开始匹配
j=0;}//子串从头开始匹配
}
if(j>=i2)
{return(i1-i2);}//返回匹配的第一个字符的下标
else
return(-1);//模式匹配不成功
}
(3)按行来实现查找
而且程序中用的顺序表存储的形式,在执行的时候考虑到在查找时,要显示是在第几行第几列的位置,但是程序并不是用二维数组来实现的,并不记录文本中每一个字符的行列号,所以如果直接一下子统计出来的话,就会出现行列号上的错误,所以在程序中使用了一下LOOP语句,来让程序一行一行的统计与显示。
当调用strindex(text,str1,t,l)函数时,得到返回值,如果a!
=-1时,得到返回的是查找的字符串的第一字符的下标,l=a+t;t是字符的长度,hs,ls,分别记录行号与列号。
loop:
a=strindex(text,str1,t,l);
if(a!
=-1)
{l=a+t;}
inths=1,ls=0;
for(i=0;i<=a;i++)
{ls++;
if(text[i]=='\n')
{hs++;ls=0;}
}if(a==-1)
{printf("查找到结尾没有找到\n输入【R】将重头查找;");
l=0;
fflush(stdin);
pd=getchar();}
else{printf("已经找到在第%d行第%d列,输入【R】继续查找下一处;",hs,ls);
kk+=1;
fflush(stdin);
bd=getchar();
if(bd=='R'||bd=='r')
gotoloop;}
(4)插入
在插入的时候是先要调用上面的查找的子函数,在插入的时候也是考虑到行列号的问题,所以我在这里也是用LOOP语句,通过一行一行的查找,找到你所要插入的地方,就进行插入操作,如果不是这个地方要插入的话,就继续往下执行查找,查找完所有的符合的,显示完后,最后统计总共有多少次。
在这个子程序中定义一个数组Cr来放置插入的位置点。
loop:
a=strindex(text,cr,t,l);//查找并返回要插入的位置点
inths=1,ls=0;
for(b=0;b{ls++;
if(text[b]=='\n')
{hs++;
ls=0;}
}
if(a==-1)
{printf("\n查找到结尾没有找到插入点,输入【R】查找其他;\n");
l=0;
d=getchar();
else
{printf("\n您要插入的位置是第%d行,第%d列之前\n",hs,ls+1);
printf("\n【A】.不是此位置向后继续找插入点\n【B】.在此位置插入\n按其他键返回菜单\n请选择:
");
pd=getchar();
if(pd=='a'||pd=='A')
{l=a+t;
gotoloop;
}
for(i=ntext;i>=a;i--)
{text[i+t2]=text[i];}
for(i=0;i{text[i+a]=x[i];}
ntext=ntext+t2;
printf("\n当前文本信息为:
\n");
for(i=0;i<=ntext-1;i++)
printf("%c",text[i]);
printf("\n文本插入成功\n");
fflush(stdin);
getchar();}
}
(5)替换
做替换的时候,定义一个数组来放替换的内容,另一个数组放替换后的内容,而且在做替换时也要调用字符匹配的子程序。
loop:
a=strindex(p,bth,t,l);//查找要被替换的内容的位置
inths=1,ls=0;
for(b=0;b{ls++;
if(p[b]=='\n')
{hs++;
ls=0;}}
if(a==-1)
{printf("\n查找到结尾没有找到要被替换的内容\n输入【R】查找其他内容\n");
l=0;
d=getchar();
else
{printf("\n\n已经找到要查找的数据在第%d行第%d列\n输入",hs,ls+1);
printf("\n【A】继续向后查找相同内容\n输入其他键将进行替换操作\n请选择:
");
l=t+a;
charpd;
pd=getchar();
if(pd!
='a'&&pd!
='A')
{printf("\n是否要替换该内容?
\nA:
替换给内容;其他键返回主菜单\n请选择:
");
d1=getchar();
if(d1=='a'||d1=='A')
{printf("\n输入要替换的内容,以@结束:
");
while((c=getchar())!
='@')//t1指替换后的内容长度
{if(c=='@')
{break;}
else
{th[t1++]=c;
continue;}
}
if(t==t1)//将要被替换的内容和替换后的内容进行长度比较
{for(i=0;ip[i+a]=th[i];}
else
{if(t>t1)
{for(i=0;i{p[i+a]=th[i];}
for(i=a+t1;i{p[i]=p[i+t-t1];}
ntext=ntext+t1-t;}
else
{for(i=ntext;i>=a;i--)
{p[i+t1-t]=p[i];}
for(i=0;i{p[i+a]=th[i];}
ntext=ntext+t1-t;}
}
printf("替换成功");
printf("\n当前文本信息为:
\n");
for(i2=0;i2<=ntext-1;i2++)
printf("%c",p[i2]);
getchar();
status=0;}}
else
gotoloop;
}
(6)删除
删除的时候,也需要调用字符匹配的子程序,找到了要删除的内容,再进行删除,
loop:
a=strindex(p,x,t2,l);
inths=1,ls=0;
for(i=0;i<=a;i++)
{ls++;
if(p[i]=='\n')
{hs++;ls=0;}
}
if(a==-1)
{printf("已查找结束,您要删除的内容不存在\n输入【R】重新输入要删除的内容;");
l=0;
fflush(stdin);
pdx=getchar();}
else
{printf("你要删除的内容在第%d行第%d列\n输入【A】确定删除;输入【B】寻找下个词;",hs,ls);
fflush(stdin);
pd=getchar();
l=t2+a;
if(pd=='a'||pd=='A')
{for(i=a;i{p[i]=p[i+t2];}
ntext=ntext-t2;
printf("删除成功,删除后的内容为:
\n%s\n",text);}
elseif(pd=='b'||pd=='B')
gotoloop;}
5.程序代码
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
voidopen(chartext[]);
voidsave(chartext[]);
voidsearch(chartext[],intl);
intstrindex(chartext[],chart[],inti2,intl);
voidoutput(chartext[]);
voidDelete(charp[],intl);
voidinsert(chartext[],intl);
voidReplace(intstatus);
voidmenu();
#defineMAX10000
chartext[MAX]="";//文本编辑域
charname[20]="";//文件保存的位置
intstatus=0;//显示是否保存过的状态
intntext;//文本编辑的位置
voidopen(chartext[])
{system("cls");
FILE*fp;
charpd,ch;
charname[30];
inti=0,ss=1;
printf("输入A:
确定打开文件M:
返回主菜单");
fflush(stdin);
pd=getchar();
if(pd=='A'||pd=='a')
{printf("请输入要打开文件名字(例如c:
\\a.txt)");
scanf("%s",name);
while((fp=fopen(name,"r"))==NULL)
{printf("\n打开文件失败,请重新输入要打开的文件名:
");
scanf("%s",name);}
system("cls");
while(!
feof(fp))
{ch=fgetc(fp);if(ch=='\n')ss++;
text[i++]=ch;}
text[i]='\0';
ntext=i;
fclose(fp);
printf("\n文件读取成功\n文件内容为\n");
output(text);
printf("有%d行",ss);
}
if(pd=='M'||pd=='m')
menu();
}
voidsave(chartext[])
{system("cls");
FILE*fp;
charpd;
chartmp;
inti;
printf("\n输入【A】保存;\n");
fflush(stdin);
pd=getchar();
if(!
(pd=='A'||pd=='a'))
{menu();}
else
{if(name[20]==NULL)
{printf("\n请输入保存文件名(例如:
c:
\\a.txt):
");
scanf("%s",name);}
while((fp=fopen(name,"w+"))==NULL)
{printf("文件不存在,请重新输入文件名:
");
scanf("%s",name);}
printf("\nA:
确定;B:
取消:
");
while(scanf("%c",&tmp)!
=EOF)
{if(tmp=='A'||tmp=='a')
{for(i=0;ifprintf(fp,"%c",text[i]);
fclose(fp);
status=1;
printf("\n文件保存成功\n");
break;
}
if(tmp=='B'||