数据结构课程设计文本编辑器

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

山东理工大学计算机学院
课程设计
(数据结构)
班级计科0906
姓名赵利强
学号0911011192
指导教师孙守卿
二○一一年一月二十日
课程设计任务书及成绩评定
课题名称文本编辑
Ⅰ、题目的目的和要求:
1、设计目的
巩固和加深对数据结构的理解,通过上机实验、调试程序,加深对课本知识的理解,最终使学生能够熟练应用数据结构的知识写程序。

(1)通过本课程的学习,能熟练掌握几种基本数据结构的基本操作。

(2)能针对给定题目,选择相应的数据结构,分析并设计算法,进而给出问题的正确求解过程并编写代码实现。

2、设计题目要求:
文章编辑
功能:输入一页文字,程序可以统计出文字、数字、空格的个数。

静态存储一页文章,每行最多不超过80个字符,共N行;要求(1)分别统计出其中英文字母数和空格数及整篇文章总字数;(2)统计某一字符串在文章中出现的次数,并输出该次数;(3)删除某一子串,并将后面的字符前移。

存储结构使用线性表,分别用几个子函数实现相应的功能;
输入数据的形式和范围:可以输入大写、小写的英文字母、任何数字及标点符号。

输出形式:(1)分行输出用户输入的各行字符;(2)分4行输出"全部字母数"、"数字个数"、"空格个数"、"文章总字数"(3)输出删除某一字符串后的文章;
Ⅱ、设计进度及完成情况
Ⅲ、主要参考文献及资料
[1] 严蔚敏数据结构(C语言版)清华大学出版社 1999
[2] 严蔚敏数据结构题集(C语言版)清华大学出版社 1999
[3] 谭浩强 C语言程序设计清华大学出版社
[4] 与所用编程环境相配套的C语言或C++相关的资料
Ⅳ、成绩评定:
设计成绩:(教师填写)
指导老师:(签字)
二○一一年一月二十一日
目录
第一章概述 (1)
第二章系统分析 (2)
第三章概要设计………………………………………………………第四章详细设计………………………………………………………第五章运行与测试……………………………………………………第六章总结与心得……………………………………………………参考文献………………………………………………………………
第一章概述
在这次课程设计中我选的题目是文本编辑,文本编辑几乎是每个使用电脑的人都会遇到的问题,特别是网络小说作家们。

在文本的编辑中,我们会时常遇到文本信息的统计问题、小型子串的查找问题、子串的查找和删除问题等。

如果靠人自己去观察和执行相关操作的话,不仅累人,而且很容易出错。

而使用计算机程序去实现的话,则会省力不少,而且相对来说非常精确。

本程序使用了较快速的查找算法(KMP),可以大大提高检索的效率,相信这可一极大的方便用户用电脑编辑文本文件。

第二章系统分析
1.文本编辑的基本内容为查看文本文件内容,统计内容基本信息,查找子串是否存在及其出现次数,查找并删除所有的相关子串并重新输出文本内容等等。

2.文本编辑所需的数据相对简单,所以本程序仅需要使用一个文本数据文件,当然该文本文件需要和本程序在同一目录下才行。

3.本程序是在终端下运行的程序,页面简洁清晰,并配有丰富的提示,即使是在终端下,其人性化依旧,对于喜欢用终端命令提示符的用户来说在编辑时会感到很惬意,对于习惯窗口形式的用户来说其人性化提示也能使用户尽快适应工作环境。

4.程序执行时的命令:
既然是终端了,那么程序执行时肯定是使用命令来进行操作了。

虽然没有窗口那样直观,但使用却非常简单、准确,用户不用担心忘记指令,随时可以调用help指令来查看相关命令。

5. 测试数据。

共有3组测试数据可供测试,小、大型数据及边界数据都有。

第三章概要设计
1、数据结构的设计
对于文本编辑来说,数据结构相对简单,使用一个有较大最大长度的顺序表即可,在程序中可采用一维数组来实现。

使用数组表示的顺序表来存储文本具有简洁、访问方便、输出方便等特点。

2、算法的设计
程序的设计总体上可分为8个模块,封装在File类内。

第1个模块是数据区,即程序运行需要使用的数据、文件流等。

第2个模块是准备部分,即程序刚开始时应输出的信息。

这里使用接口函数void File::Getready()实现,伪代码如下:
void File::Getready()
{
cout<<"相关信息及注意事项.."<<endl;
cout<<"相关信息及注意事项.."<<endl;
}
第3个模块是数据读取部分,即从文件中获得所需文本信息。

使用接口函数void File::Getdata()实现,伪代码如下:
void File::Getdata()
{
cin>>filename;
fin.open(filename);
cout<<"正在读取数据...."<<endl;
len = 0;
while(fin.getline(text,81,'\n'))
{
strcat(s, text);
len += strlen(text);
s[len] = '\n';
s[++len] = '\0';
}
cout<<"数据初始化完毕..."<<endl<<endl;
}
第4个模块是输出文本内容部分,使用接口函数void File::Show_text()实现。

伪代码入下:
void File::Show_text()
{
cout<<"您的输入文件内容如下:"<<endl<<endl;
cout<<"数据区线性表存储的文本内容"<<endl<<endl;
}
第5个模块是帮助命令模块部分,调用该模块可以在终端显示程序执行时用户可调用的所有指令,以方便用户记忆和使用。

该部分使用接口函数void File::Help()实现,伪代码如下:
void File::Help()
{
cout<<"您可以使用以下命令"<<endl<<endl;
cout<<"指令1功能及其使用方法"<<endl<<endl;
cout<<"指令2功能及其使用方法"<<endl<<endl;
cout<<"指令3功能及其使用方法"<<endl<<endl;
cout<<"指令4功能及其使用方法"<<endl<<endl;
cout<<"指令5功能及其使用方法"<<endl<<endl;
}
第6个模块是统计信息部分,该模块用来统计文本信息并通过终端将信息传递给用户。

该部分通过接口函数void File::Count()实现,伪代码如下:
void File::Count()
{
int cc, cp, i, cn;
cc = cp = cn = 0;
for(i = 0; i < len; i++)
{
扫描过程中统计字母数、数字数、空格数、总字符数等相关信息。

}
cout<<"文章字数信息统计如下: "<<endl<<endl;
cout<<"全部字母数: "<<cc<<endl<<endl;
cout<<"数字个数: "<<cn<<endl<<endl;
cout<<"空格个数: "<<cp<<endl<<endl;
cout<<"文章总字数: "<<len<<endl<<endl;
}
第7个模块是子串查找部分,该部分会对用户在终端输入的字符串在文本中进行检索,并将其出现次数反馈给用户。

该部分使用接口函数void File::Count_str()实现,伪代码如下:
void File::Count_str()
{
int i, j, ls, ct = 0;
cin.get();
cin.getline(str, '80', '\n');
ls = strlen(str);
memset(next, -1, sizeof(next));//以上为数据的输入及预处理
求子串的前缀函数next
使用前缀函数next,用KMP算法进行匹配、查找和统计
cout<<str<<" 在文章中的出现次数为: "<<ct<<endl<<endl;
}
第8个模块是查找并删除所有子串部分。

该部分会对用户在终端输入的字符串进行查找,并将原文本中所有该子串进行删除,使用接口函数void File::Delete_str()实现,伪代码如下:
void File::Delete_str()
{
int i, j, ls, k;
memset(visit, false, sizeof(visit));
cin.get();
cin.getline(str, '80', '\n');
ls = strlen(str);
memset(next, -1, sizeof(next)); //子串读入及数据的预处理
计算前缀函数next
i = j = 0;
使用next函数及稍加修改的KMP算法匹配并删除原文本中所有用户输入的子串
len = strlen(s);
cout<<s<<endl;
}
第四章详细设计
#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 80010;
class File
{
private:
char s[N];
char filename[260];
char text[90];
char str[90];
int len, next[90];
bool visit[N];
ifstream fin;
void Getready();
void Getdata();
void Show_text();
void Count();
void Count_str();
void Delete_str();
void Help();
public:
File()
{
cout<<"欢迎使用文章编辑工具版权所有:SDUT 计科0906
zlq"<<endl<<endl;
memset(s, 0, sizeof(s));
len = 0;
}
void Main_Work();
~File()
{
cout<<"谢谢您的支持,如有建议和意见,请发送到zlqest@,谢谢合作"<<endl<<endl;
};
void File::Getready()
{
cout<<"请输入数据文件名(包括扩展名,只能有英文、数字和点号)"<<endl<<endl;
cout<<"注意:由于资源控制,请保证输入不超过1000行,每行不超过80个字符,查询的子串长度不得超过一行"<<endl<<endl;
cout<<"文件名: "; /*让子串长度不超过一行是为了防止某些用户在终端中不会用Ctrl+Z来表示EOF*/
}
void File::Getdata()
{
cin>>filename;
fin.open(filename);
cout<<"正在读取数据...."<<endl;
len = 0;
while(fin.getline(text,81,'\n'))
{
strcat(s, text);
len += strlen(text);
s[len] = '\n';
s[++len] = '\0';
}
cout<<"数据初始化完毕..."<<endl<<endl;
}
void File::Show_text()
{
cout<<"您的输入文件内容如下:"<<endl<<endl;
cout<<s<<endl<<endl;
}
void File::Help()
cout<<"您可以使用以下命令"<<endl<<endl;
cout<<"count : 分别统计出其中英文字母数和空格数及整篇文章总字数
"<<endl<<endl;
cout<<"search(+换行输入所要查找的字符串): 统计某一字符串在文章中出现的次数,并输出该次数"<<endl<<endl;
cout<<"delete(+换行输入所要删除的字符串): 删除某一子串,并将后面的字符前移"<<endl<<endl;
cout<<"help: 查看程序命令集"<<endl<<endl;
cout<<"exit: 退出应用程序"<<endl<<endl;
}
void File::Count()
{
int cc, cp, i, cn;
cc = cp = cn = 0;
for(i = 0; i < len; i++)
{
if(s[i]>='0' && s[i]<='9')
{
cn++;
continue;
}
if(s[i]>='A' && s[i]<='Z')
{
cc++;
continue;
}
if(s[i]>='a' && s[i]<='z')
{
cc++;
continue;
}
if(s[i] == ' ')
{
continue;
}
}
cout<<"文章字数信息统计如下: "<<endl<<endl;
cout<<"全部字母数: "<<cc<<endl<<endl;
cout<<"数字个数: "<<cn<<endl<<endl;
cout<<"空格个数: "<<cp<<endl<<endl;
cout<<"文章总字数: "<<len<<endl<<endl;
}
void File::Count_str()
{
int i, j, ls, ct = 0;
cin.get();
cin.getline(str, '80', '\n');
ls = strlen(str);
memset(next, -1, sizeof(next));
i = 1;
while(i < ls)
{
j = next[i-1];
while(j>-1 && str[j+1]!=str[i]) j = next[j]; if(j != -1) next[i] = j + 1;
i++;
}
i = j = 0;
while(i < len)
{
if(s[i] != str[j])
{
j = next[j];
if(j == -1)
{
i++;
}
}
else
{
i++;
j++;
}
if(j == ls)
{
ct++;
j = 0;
}
}
cout<<str<<" 在文章中的出现次数为: "<<ct<<endl<<endl; }
void File::Delete_str()
{
int i, j, ls, k;
memset(visit, false, sizeof(visit));
cin.get();
cin.getline(str, '80', '\n');
ls = strlen(str);
memset(next, -1, sizeof(next));
i = 1;
while(i < ls)
{
j = next[i-1];
while(j>-1 && str[j+1]!=str[i]) j = next[j];
if(j != -1) next[i] = j + 1;
i++;
}
i = j = 0;
while(i < len)
if(s[i] != str[j])
{
j = next[j];
if(j == -1)
{
i++;
j = 0;
}
}
else
{
i++;
j++;
}
if(j == ls)
{
for(k = i-ls; k < i; k++) visit[k] = true; j = 0;
}
}
i = j = 0;
while(j < len)
{
while(j<len && visit[j]) j++;
if(j == len) break;
s[i++] = s[j++];
}
s[i] = '\0';
len = strlen(s);
cout<<s<<endl;
}
void File::Main_Work()
{
this->Getready();
this->Getdata();
this->Show_text();
Help();
cout<<"请输入指令: ";
while(cin>>order)
{
cout<<endl;
if(strcmp(order, "exit") == 0) return;
if(strcmp(order, "count") == 0) Count();
else
if(strcmp(order, "search") == 0) Count_str();
else
if(strcmp(order, "delete") == 0) Delete_str();
else
if(strcmp(order, "help") == 0) Help();
else cout<<"非法指令,请重新输入。

"<<endl<<endl;
cout<<"请输入指令: ";
}
}
int main()
{
File Text;
Text.Main_Work();
return 0;
}
第五章运行与测试
1、设计中遇到的问题
(1)使用文件读入时,刚开始我选用C的freopen进行重定向,导致无法和终端的输入区分开来,查阅了一下数据,最终用C++的输入文件流解决了这个问题。

(2)对KMP前缀函数进行编写时刚开始采用了课本上讲的方式,但实践中发现课本上的方式在该问题的编码中并不是非常的简洁,于是经过自己的推导和对原算
法的一点修改使前缀函数计算和KMP匹配是更加的流畅,代码更加简洁。

2、测试数据及其结果
程序运行时自动显示下列信息:
欢迎使用文章编辑工具版权所有:SDUT 计科0906 zlq
请输入数据文件名(包括扩展名,只能有英文、数字和点号)
注意:由于资源控制,请保证输入不超过1000行,每行不超过80个字符,查询的子串长度不得超过一行
文件名:
(1) data1.txt测试数据及终端输入指令运行结果如下:
(2)data2.txt测试数据及终端输入指令运行结果如下:(3)data2.txt测试数据及终端输入指令运行结果如下:
第六章总结与心得
充分体会到了C++在大规模程序设计中的作用,更好的体会了数据封装的意义。

写程序是练出来的不是看出来的
高效的程序往往能带了更好的体验。

写程序要有耐心
充分体会到了数据结构在实际中的应用。

充分体会到了一个真理——算法和数据结构是程序的灵魂。

参考文献:
[1] 严蔚敏、吴伟民主编《数据结构》(C语言版)清华大学出版社 2002
[2] 殷人昆等著《数据结构》(C++版)清华大学出版社 2001
[3] 金远平著《数据结构》(C++描述)清华大学出版社 2005
[4] 许卓群等著《数据结构与算法》高等教育出版社 2004
[5] Frank M.Carrano 等著《数据结构与C++高级教程》清华大学出版社 2004
[6] 严蔚敏、吴伟民《数据结构习题集》(C语言版)清华大学出版社
17。

相关文档
最新文档