数据结构 文章编辑
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
【完成题目4】文章编辑
【问题描述】
输入一页文字,程序可以统计出文字、数字、空格的个数;
静态存储一页文章,每行最多不超过80个字符,共N行。
【基本要求】
1.分别统计出其中英文字母数和空格数及整篇文章总字数;
2.统计某一字符串在文章中出现的次数,并输出该次数;
3.删除某一子串,并将后面的字符前移。
存储结构使用线性表,分别用几个子函数实现相应的功能;
输入数据的形式和范围:可以输入大写、小写的英文字母、任何数字及标点符号。
输出形式:
1.分行输出用户输入的各行字符;
2.分4行输出"全部字母数"、"数字个数"、"空格个数"、"文章总字数";
3.输出删除某一字符串后的文章。
【算法设计】
统计str在文章中出现次数的思路
1.查找第一个字符,如果有第一个字符即p->data[i]==str[0],设计数器k=0。
2.查找这个字符后面的字符与要查找的字符串是否匹配即p->data[i+j]==str[j],如果匹配k++。
3.重复第二步,如果k=len2,则查找到,count++;如果没查找到,重新进行第一步。
删除指定字符串的思路
1.从字符串s中寻找str第一次出现的位置 *p=strstr(s,str)。
2.len=strlen(s);i=len-strlen(p)即前i项恰好不含要删除的字符串,将前i项复制到tmp中。
3.j=i+strlen(str) 即要删除的字符串在i+1和j之间,将j之后的字符串复制到tmp 中。
4.将tmp赋给串s,返回s。
【源代码】
#include<iostream.h>
#include <string.h>
#include <stdio.h> /*文本每行以字符串形式存储,行与行之间以链表存储*/
typedef struct line
{
char *data;
struct line *next;
}LINE; /*创建一链表,同时向里面输入文本数据*/
void Create(LINE * &head)
{
printf ("请输入一页文章,以Ctrl+E(^E)为结尾 (每行最多输入80字符!):\n");
LINE *p=new LINE; /*首先为链表建立一个附加表头结点*/ head=p; /*将p付给表头指针*/
char tmp[100];
while(1)
{
gets(tmp); /*输入字符串!*/
if(strlen(tmp)>80)
{
printf("每行最多输入80字符");
break;
}
if(tmp[0]==5)break; /*如果发现输入 ^E,则退出输入*/
p=p->next=new LINE;
p->data=new char[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;
}
/*统计字母数*/
int CountLetter(LINE * &head)
{
LINE *p=head;
int count=0;
do
{
int Len=strlen(p->data); /*计算当前 data 里的数据元素的个数*/
for(int i=0;i<Len;i++)
if((p->data[i]>='a'&&p->data[i]<='z')||(p->data[i]>='A'&&p->data[i]<='Z')) /*计算字母数*/
count++;
}
while((p=p->next)!=NULL); /*遍历链表*/
return count; /*返回文章的字母总数*/
}
/*统计数字数*/
int CountNumber(LINE * &head)
{
LINE *p=head;
int count=0;
do
{
int Len=strlen(p->data); /*计算当前 data 里的数据元素的个数*/ for(int i=0;i<Len;i++)
if(p->data[i]>=48 && p->data[i]<=57)count++;
/*计算数字数,ASCII码*/
}
while((p=p->next)!=NULL); /*遍历链表*/
return count;
}
/*统计空格数*/
int CountSpace(LINE * &head)
{
LINE *p=head;
int count=0;
do
{
int Len=strlen(p->data); /*计算当前 data 里的数据元素的个数*/ for(int i=0;i<Len;i++)
if(p->data[i]==32)count++; /*计算空格数,空格ASCII码为32*/ }
while((p=p->next)!=NULL); /*遍历链表*/
return count;
}
/*统计文章的总字数*/
int CountAll(LINE * &head)
{
LINE *p=head; /*保存链表的首地址*/ int count=0;
do /*计算总字符数*/
{
count+=strlen(p->data);
}
while((p=p->next)!=NULL); /*遍历链表*/
return count;
}
/*统计str在文章中出现的次数*/
int FindString(LINE * &head,char *str)
{
LINE *p=head;
int count=0;
int h=0;
int len1=0; /*保存当前行的总字符数*/ int len2=strlen(str); /*待统计字符串的长度*/ int i,j,k;
do
{
len1=strlen(p->data); /*当前行的字符数*/
for(i=0;i<len1;i++) /*字符匹配*/
{
if(p->data[i]==str[0])
{
k=0;
for(j=0;j<len2;j++)
if(p->data[i+j]==str[j]) k++;
if(k==len2) {count++;i=i+k-1;}
}
}
}
while((p=p->next)!=NULL); /*遍历链表*/
return count;
}
/*删除指定的字符串*/
void delstringword(char *s,char *str)
/* *s为输入的字符串,*str为将要删除的字符*/
{
char *p=strstr(s,str); /*从字符串s中寻找str第一次出现的位置*/
char tmp[80];
int len=strlen(s);
int i=len-strlen(p);
int j=i+strlen(str);
int count=0;
for(int m=0;m<i;m++)tmp[count++]=s[m];
for(int n=j;n<len;n++)tmp[count++]=s[n];
tmp[count]='\0';
strcpy(s,tmp); /*返回新的字符串*/
}
void DelString(LINE * &head,char *str)
{
LINE *p=head;
do
{
if(strstr(p->data,str)!=NULL)delstringword(p->data,str);
}
while((p=p->next)!=NULL); /*遍历链表*/ }
/*向屏幕输出文章*/
void OutPut(LINE * &head)
{
LINE *p=head;
do
{
printf("%s\n",p->data);
}
while((p=p->next)!=NULL); /*遍历链表*/
}
void main()
{
LINE *head;
Create(head);
printf("输入的文章为:\n");
OutPut(head);
printf("\n");
printf("全部字母数:%d \n",CountLetter(head));
printf("数字个数:%d \n",CountNumber(head));
printf("空格个数: %d \n",CountSpace(head));
printf("文章总字数: %d \n",CountAll(head));
char str1[20],str2[20];
printf("\n");
printf("请输入要统计的字符串:");
scanf("%s",str1);
printf("%s出现的次数为:%d \n",str1,FindString(head,str1));
printf("\n");
printf("请输入要删除的某一字符串:");
scanf("%s",str2);
DelString(head,str2);
printf("删除%s后的文章为:\n",str2);
OutPut(head);
}
【结果截图】
【收获及体会】
做这个实验时,我有想到输入文章时计算机怎样识别文章是否结束,输出文章时,怎样处理表示结束的字符。
通过上网了解和与同学交流后,我以Ctrl+E(^E)为结尾,当tmp[0]==5时,发现输入 ^E,则退出输入。
输出文章时,如果tmp[strlen(tmp)-1]==5即发现表示结束的字符^E,用p->data[strlen(tmp)-1]='\0'除去最后一个控制符 ^E。
由于本程序的文章为用户输入的文章,只能做即时输入的统计、编辑,而不能对已有的磁盘文件中的文章进行统计、编辑,如果引入文件流类,就可以打开磁盘文件,对其进行统计、编辑并保存,这是有待改进的。
此次课程设计使我对数据结构方面的知识有了更加深入的了解,也使我认识到自己在学习编程方面还有很多的不足。
今后我要多读一些编程方面的书籍,不能只拘泥于课本上的知识,并注重理论与实践的结合,多上机练习编写程序,提高自己的实际动手能力和独立思考的能力,不断充实自己,更好的掌握编程思想。