数据结构课程设计—简单行编辑程序

news2024/9/28 17:25:42

简单行编辑程序

一、引言

1.1 问题的提出

文本编辑程序是利用计算机进行文字加工的基本软件工具,实现对文本文件的插入、删除等修改操作。限制这些操作以行为单位进行的编辑程序称为行编辑程序。

被编辑的文本文件可能很大,全部读入编辑程序的数据空间(内存)的作法既不经济,也不总能实现。一种解决方法是逐段地编辑。任何时刻只把待编辑文件的一段放在内存,称为活区。试按照这种方法实现一个简单的行编辑程序。设文件每行不超过320个字符,很少超过80个字符。

实现以下4条基本编辑命令:

(1) 行插入。格式:i<行号><回车><文本>.<回车>

将<文本>插入活区中第<行号>行之后。

(2) 行删除。格式:d<行号l>[<空格><行号2>]<回车>

删除活区中第<行号l>行(到第<行号2>行)。例如:"d10"和"d1014"。

(3) 活区切换。格式n<回车>

将活区写入输出文件,并从输入文件中读入下一段,作为新的活区。

(4) 活区显示。格式:p<回车>

逐页地(每页20行)显示活区内容,每显示一页之后请用户决定是否继续显示以后备页(如果存在)。印出的每一行要前置行号和一个空格符,行号固定占4位,增量为1。

各条命令中的行号均须在活区中各行行号范围之内,只有插入命令的行号可以等于活区第一行行号减1,表示插入当前屏幕中第一行之前,否则命令参数非法。

1.2 任务需求分析

程序对文字以行为单位进行编辑,功能有行的插入、行的删除、行的交换和进入下一页。要求用文本文件输入数据,并将修改好的数据保存到另一个文件中。因输入文件可能太大,不能将数据一次性全部输入,仅输入一部分。

首先要从文件中将数据读入内存,要以行为单位,而不能以每个字或每句话为单位。因此要定义一个结构体,存储一行的内容。而要使编辑方便,需要每行的编号,因此在结构体中要加入一个存储行号的变量。

但从文件中读数据不能一次全读完,因此定义一个活区的类,这个类里包含了行的数量和行的结构体变量。

接着将文件内容输出到显示器,将活区的内容分次输出。

下面就是对数据的处理了,每行的内容存储到结构体数组中,删除操作只需将后一个的把前一个覆盖,并将数组数量减一。

插入操作,将数组数量加一,从后向前到插入处,把前一个覆盖后一个。然后将要插入的内容写入插入处即可。

二、代码分析

2.1 设计思想

本课程设计主要解决在文本编辑中,对行编辑的问题,通过字符串完善对文本的编辑,实现对文本的查找、替换、和修改数据。在程序设计中采用了字符串的方法实现对简单的行编辑器。程序通过调试运行,初步实现了设计目标,并且经过适当完善后,将可以应用在实际中解决问题。用字符串实现一个简单的行编辑器,其中包括字符的按行录入、修改、替换、查询。用栈实现简单的行编辑程序,文本编辑程序是利用计算机进行文字加工的基本软件工具,实现对文本文件的插入、删除等修改操作。限制这些操作以行为单位进行的编辑程序称为行编辑程序。被编辑的文本文件可能很大,全部读入编辑程序的数据空间(内存)的做法即不经济,又不易实现。一种解决方法是逐段的编辑。任何时刻只把待编辑文件的一段放在内存,称为活区。

通过《简单行编辑程序》的设计过程,我学会了分析研究数据结构的特性,以便为应用涉及的数据选择适当的逻辑结构,存储结构及相应的算法,并初步掌握算法的时间分析和空间分析的技术。一方面,通过该题目设计工程,也是复杂程序设计的训练过程,要求我编写程序设计结构清楚和正确易读,符合软件工程的规范。

2.2 基础知识

2.2.1栈的概念和特性

栈(stack)是一种特殊的线性表。作为一个简单的例子,可以把食堂里冼净的一摞碗看作一个栈。在通常情况下,最先冼净的碗总是放在最底下,后冼净的碗总是摞在最顶上。而在使用时,却是从顶上拿取,也就是说,后冼的先取用,后摞上的先取用。如果我把冼净的碗“摞上”称为进栈(压栈),把“取用碗”称为出栈(弹出),那么上例的特点是:后进栈的先出栈。然而,摞起来的碗实际上是一个线性表,只不过“进栈”和“出栈”都在最顶上进行,或者说,元素的插入和删除操作都是在线性表的一端进行而已。

一般而言,栈是一个线性表,其所有的插入和删除操作均是限定在线性表的一端进行,允许插入和删除的一端称栈顶(Top),不允许插入和删除的一端称栈底(Bottom)。若给定一个栈S=(a1, a2,a3,……,an),则称a1为栈底元素,an为栈顶元素,元素ai位于元素ai-1之上。栈中元素按a1, a2,a3,……,an 的次序进栈,如果从这个栈中取出所有的元素,则出栈次序为an, an-1,……,a1 。也就是说,栈中元素的进出是按后进先出的原则进行,这是栈结构的重要特征。因此栈又称为后进先出(LIFO—Last In First Out)表。


我常用一个图来形象地表示栈,其形式如图2-1:

图2-1 栈操作示意图

通常,对栈进行的操作主要有以下几种:

⑴在使用栈之前,首先需要建立一个空栈,称建栈(栈的初始化);

⑵往栈顶加入一个新元素,称进栈(压栈、入栈);

⑶删除栈顶元素,称出栈(退栈、弹出);

⑷查看当前的栈顶元素,称读栈;{注意与⑶的区别}

⑸在使用栈的过程中,还要不断测试栈是否为空或已满,称为测试栈。

2.2.2栈的存储结构

(1)顺序栈

栈是一种线性表,在计算机中用一维数组作为栈的存储结构最为简单,操作也最为方便。例如,设一维数组STACK[1…n] 表示一个栈,其中n为栈的容量,即可存放元素的最大个数。栈的第一个元素,或称栈底元素,是存放在STACK[1]处,第二个元素存放在STACK[2]处,第i个元素存放在STACK[i]处。另外,由于栈顶元素经常变动,需要设置一个指针变量top,用来指示栈顶当前位置,栈中没有元素即栈空时,令top=0;当top=n时,表示栈满。

如果一个栈已经为空,但用户还继续做出栈(读栈)操作,则会出现栈的“下溢”;如果一个栈已经满了,用户还继续做进栈操作,则会出现栈的“上溢”。这两种情况统称为栈的溢出。

建栈的操作很简单,只要建立一个一维数组,再把栈顶指针置为零即可。栈的容量根据具体的应用要求而定,一般要定义的足够大。如:

type arraytype= array[1.. n] of integer;

var stack:arraytype;

top:integer;

(2)链式栈

当我学可指针和链表后,也可以用链表来模拟栈(链式栈),这样可以提高空间利用率,但编程复杂度提高了。定义方法如下:

type link=^node

node=record

data: integer;

next:link

end;

var hs:link;

链式栈如图
2-2

图2-2 链式栈示意图

2.3程序模块设计

2.3.1 主函数设计

栈是一种先进后出的线性表,为了能按照原来的输入顺序输出元素,我在程序中设计了两个栈,第一个栈用来存储输入的字符,然后把第一个栈的元素出栈,并且把出栈的元素放入第二个栈中,这样就实现了出栈是元素的顺序和最开始输入的顺序是一致的了。

首先,构造一个空栈函数Createlist();然后设计输入函数push(SqStack &S,char e)和出栈函数pop(SqStack &S,char &e);在这两个函数里,我通过顶指针的增加(S.top++=e)和指针的减少来实现元素的进栈和出(e=–S.top)。


我通过设计函数int insert()来进行行插入操作,通freemem()来清空栈中所有的元素,通过使用free()函数来释放top的地址。通过函int saveanddisplay(int hang)输出显示输入的所有元素。具体流程如图2-3。

图2-3 主函数流程图

2.3.2 删除模块设计

代码如下:

void delstringword(char *s,char *str)     

 {

char *p=strstr(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);  

                        }

在函数的开始定义了三个指向struct text结构体的指针变量p1,p2,p3。输入要删除的两个行号(比如1 3),表示删除从第1行到第3行的数据。程序流程图如图2-4所示。

执行行删除功能时,由主函数调用删除函数删除所需删除行,再调用显示函数,显示执行行删除后的文本。


int del(textp head)//删除d命令对应的函数,用来删max-min中的行,用结构体中的flat表示是否被删除。

图2-4 删除模块流程图

2.3.3 插入模块

代码如下:

void insertString()

{

    int row, col;       

    char insstr[MAXLEN];

    char newstr [MAXLEN];   

    char *myline;       

    interPosition(&row, &col);

    myline = buf[row];

    printf("插入字符串:");

    scanf("&s",insstr);

    if(strlen(myline) + strlen(insstr) >= MAXLEN)

       return;

      

    sprintf (newstr, "%s%s",insstr, myline + col);

    strcpy (myline + col, newstr);

    printf("&04d:8s\n", row, myline);

}

行插入函数的开始定义了三个指向struct text结构体的指针变量p,p1,p2,在给hang赋初值后使p1指向头结点,利用for循环,找到要插入行的前一行hang-1,然后

给插入的行分配内存空间。输入文本内容并连入链表。

2.3.4 活区切换格式模块

活区切换函数实现活区之间的切换,把文本的每一页(20行)作为一个活区,可以逐页的把活区内容显示出来。在活区切换函数中定义了一个指向struct text结构体的指针变量p赋初值*p=NULL,当i小于20时,如果行没有被删除(flag=1)就通过fputs函数把活区内容写入到文件(out)流程图如2-5 所示。

图2-5 活区切换格式模块流程图

2.3.5 活区显示格式模块

代码如下:

void listLines()

{

    int n;

    for(n=0;n<lines;n++) printf("%04d:%s\n",n,buf[n]);

}

void gotoLine()

{

    int n;

    scanf("%d",&n);

    if(0<=n && n<lines)  printf("%04d:%s\n",n,buf[n]);

}

显示函数display()在程序运行过程中经常得以调用,是行编辑程序中极其重要的一个函数。行编辑程序通过对显示函数display()的调用,在程序执行行插入、行删除等编辑功能后,输出编辑后的文本。

在活区显示中首先把文本内容链入链表,函数中用page来实现页码的自增。函数种定义了一个指向struct text结构体的指针变量p ,在文件fp非空和行号小于20的情况下,利用fgets函数使p->string从打开的文件fp中得到字符的值,然后输出每一行的行号和每一行的内容。其程序流程图如图2-6所示。

图2-6 活区显示格式模块流程图

三、内核调试

3.1 调试分析

3.1.1 算法的时间复杂度和空间复杂度

1.时间复杂度

一个算法的时间复杂度,是指执行算法所需要的计算工作量。通常,对于一个给定的算法,我要做两项分析。第一是从数学上证明算法的正确性,这一步主要用到形式化证明的方法及相关推理模式,如循环不变式、数学归纳法等。而在证明算法是正确的基础上,第二步就是分析算法的时间复杂度。算法的时间复杂度反映了程序执行时间随输入规模增长而增长的量级,在很大的程度上能很好的反映出算法的优劣与否。

一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行才能知道。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数越多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我想知道它变化时呈现什么规律。为此,我引入时间复杂度概念。一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得n趋近于无穷大时,T(n)/f(n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度,简称时间复杂度。

2.空间复杂度

一个程序的空间复杂度是指运行完一个程序所需内存的大小。利用程序的空间复杂度,可以对程序的运行所需要的内存多少有个预先估计。一个程序执行时除了需要存储空间和存储本身所使用的指令、常数、变量和输入数据外,还需要一些对数据进行操作的工作单元和存储一些为现实计算所需信息的辅助空间。

3.2 测试结果

测试数据:任意的TXT文件,只要每行不超过80个字符。进入程序的界面,出现命令的帮助信息,按任意键开始程序编辑。输入INPUT文件与OUTPUT文件的名字打开相应的文件 。输入P命令显示活区的内容。

其它的命令操作如下:

行插入格式: i<行号><回车><文本><回车>

行删除格式: d<回车><行号1>[<空格><行号2>]<回车>

活区切换格式: n<回车>

清屏格式: c<回车>

帮助格式: h<回车>

最后输入e命令退出程序。

(1)
在程序运行初始状态,界面显示如图3-1。提示用户输入任意键进行其他功能。

图3-1 程序主界面图

(2)输入任意键后,用户可根据自己的要求,在输入文件名的情况下输入其他命令。如图3-2。

图3-2 显示文件图


(3)行插入执行过程。在键盘上输入i回车i1i2后,在文本第二行插入i1i2字符串。如图3-3。

图3-3 插入执行图

(4)执行行删除,输入活动区切换等指令后,便会出现图3-4界面。

图3-4 删除执行图

5)建立a.txt文件,用于程序执行测试。如图3-5

图3-5 测试文件图

(6) 计算机中存储的文本b.txt本是一个空文本文档,但在执行完程序后,文本中出现了程序运行的如图3-6最终结果。

图3-5 结果文件图

四、课程设计总结

本次课程设计的内容是简单行编辑程序。经过一个周,我完成了本次课程设计,过程可谓曲折。在此过程中,构思,编写程序代码的过程是最花费时间的,对于我而言,编写一个简单行编辑程序有些困难,每天对着电脑,查阅各种资料。在程序的调试中,经常会遇到这样那样的错误,有的是因为对基本知识点不熟悉,造成的语法错误,有的是由于粗心,造成的错误,所以导致了程序的不能正常运行。每个实验通常都要花很长时间才能够理清一个程序的思路,而且要不断地调试程序,同时还要做到界面的美化。在此期间,整个课程设计的过程中让我严肃认真的对待本次课程设计,所以让我很回味这整个过程,最终,在我一起的努力下,最终完成了本次任务。

在这次课程设计中,使我懂得了理论与实际相结合是非常重要的。只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能提高自己的思考和解决问题以及实际动手能力。同时也巩固和加深了我对数据结构的进一步掌握, 提高综合运用本课程所学知识的能力,培养了我运用参考书,查阅手册及文献资料的能力,培养独立思考,深入研究,分析问题,解决问题的能力。通过实际对编译系统的分析设计,编程调试,掌握应用软件的分析方法和设计方法。而且,在做课程设计的同时也是对课本知识的巩固和加强,平时看课本时,有些问题就不是很理解,做完课程设计,这些问题就迎刃而解了,还可以记住很多东西。

认识来源于实践,实践是认识的最终目的,所以这个学期期末的数据结构课程设计对我来所作用非常大,让我更加了解数据结构的重要性,它将会在我的专业发展中发挥重要的作用。有了这次课程设计,我相信在以后的课程设计制作中,能够轻松并高质量的完成。

参考文献

[1]严蔚敏,吴伟明;《数据结构》(C语言版),清华大学出版社,2007年

[2]韩海,梁庆中;《程序设计:C语言》,科学出版社,2015年

[3]谭浩强.C语言程序设计(第2版)学习指导.北京:清华大学出版社,2009.

[4]杨莉,龚义建.C语言程序设计实训指导教程.武汉:华中科技大学出版社,2009.

[5]张小东,郑宏珍.C语言程序设计与应用.北京:人民邮电出版社,2009.

[6]郭翠英.C语言课程设计案例精编.北京:中国水利水电出版社,2004.

[7]伍一,孔凡辉,孙柏祥.数据结构应用教程(第二版).清华大学出版社,2012.

[8]胡学刚.数据结构(c语言版).北京:高等教育出版社,2007.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/353926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

强化学习基础知识

强化学习是一种机器学习方法&#xff0c;通过agent与environment的互动&#xff0c;学习适当的action policy以取得更大的奖励reward。本篇博客介绍强化学习的基础知识&#xff0c;与两类强化学习模型。 目录强化学习的基础设定policy based 强化学习的目标3个注意事项实际训练…

Python:跳蚱蜢(BFS判重)

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 如下图所示&#xff1a; 有 9 只盘子&#xff0c;排成 1 个圆圈。 其中 8 只盘子内装着 8 只蚱蜢&#xff0c;有一个是空盘。 我们把这些蚱蜢顺时针编号为 1 ~ 8。 …

Java【数据结构】—— 冒泡排序、选择排序、直接插入排序

Java实现冒泡排序、选择排序、直接插入排序一、排序的概念及稳定性二、冒泡排序1.基本思想2.代码实现三、选择排序1.基本思想2.代码实现四、直接插入排序1.基本思想2.代码实现五、复杂度及稳定性分析1.冒泡排序2.选择排序3.直接插入排序一、排序的概念及稳定性 - 概念&#xf…

文件断点续传

1、前端上传文件前请求媒资接口层检查文件是否存在&#xff0c;如果已经存在则不再上传。 2、如果文件在系统不存在前端开始上传&#xff0c;首先对视频文件进行分块 3、前端分块进行上传&#xff0c;上传前首先检查分块是否上传&#xff0c;如已上传则不再上传&#xff0c;如…

奇舞周刊第482期:每天都在用,也没整明白的 React Hook

记得点击文章末尾的“ 阅读原文 ”查看哟~下面先一起看下本期周刊 摘要 吧~奇舞推荐■ ■ ■每天都在用&#xff0c;也没整明白的 React Hook推荐理由&#xff1a;针对我们经常使用的 React Hook&#xff0c;本文详细介绍了 useState、useEffect、useContext、useCallback、use…

IP协议格式、IP地址管理、路由选择

目录 一、IP协议格式 16位总长度 ip协议针对传输层的UCP协议或者TCP协议&#xff0c;进行传输的时候&#xff0c;需不需要进行分片传输&#xff08;拆包传输&#xff09; 如何进行分片 和 组合分片 8位生存时间&#xff1a; 8位协议、16位校验和、32位源端口、32位目的端…

Agilent E4982A、Keysight E4982A、LCR 表,1 MHz 至 3 GHz

Agilent E4982A、Keysight E4982A、HP E4982A LCR 表&#xff0c;1 MHz 至 3 GHz 产品概览 KEYSIGHT E4982A&#xff08;安捷伦&#xff09; Keysight E4982A LCR 表为需要高频&#xff08;1 MHz 至 3 GHz&#xff09;阻抗测试的无源元件制造行业提供一流的性能&#xff0c…

Redis实战11-实现优惠券秒杀下单

本篇&#xff0c;咱们来实现优惠券秒杀下单功能。通过本篇学习&#xff0c;我们将会有如下收获&#xff1a; 1&#xff1a;优惠券领券业务逻辑&#xff1b; 2&#xff1a;分析在高并发情况下&#xff0c;出现超卖问题产生的原因&#xff1b; 3&#xff1a;解决超卖问题两种方…

快速排序算法原理 Quicksort —— 图解(精讲) JAVA

快速排序是 Java 中 sort 函数主要的排序方法&#xff0c;所以今天要对快速排序法这种重要算法的详细原理进行分析。 思路&#xff1a;首先快速排序之所以高效一部分原因是利用了离散数学中的传递性。 例如 1 < 2 且 2 < 3 所以可以推出 1 < 3。在快速排序的过程中巧…

C++——C++11 第一篇

目录 统一的列表初始化 &#xff5b;&#xff5d;初始化 decltype ​编辑 nullptr STL中一些变化 右值引用和移动语义 左值引用和右值引用 总结 左值引用优缺点 右值引用&#xff08;将亡值&#xff09; 拷贝赋值和移动赋值 万能引用|完美转发 移动构造和移动赋值注意…

C#操作字符串方法 [万余字总结 · 详细]

C#操作字符串方法总结C#常用字符串函数大全C#常用字符串操作方法C#操作字符串方法总结C#常用字符串函数大全 Compare 比较字符串的内容&#xff0c;考虑文化背景(场所)&#xff0c;确定某些字符是否相等 CompareOrdinal 与Compare一样&#xff0c;但不考虑文化背景 Format 格…

5.3 BGP路由黑洞

5.2.3实验3:BGP路由黑洞 1. 实验目的 熟悉BGP路由黑洞的应用场景掌握BGP水平分割的配置方法2. 实验拓扑 实验拓扑如图5-3所示: 图5-3:BGP路由黑洞 3. 实验步骤 配置IP地址 R1的配置 <Huawei>syst

前端开发常用案例(一)

前端开发常用案例1.实现三角形百度热榜样式分页效果小米商城自动轮播图效果二级下拉菜单效果时间轴效果展示音乐排行榜效果鼠标移入文字加载动画鼠标悬停缩放效果1.实现三角形 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8…

CCNP350-401学习笔记(51-100题)

51、Which statement about a fabric access point is true?A. It is in local mode and must be connected directly to the fabric edge switch. B. It is in local mode and must be connected directly to the fabric border node C. It is in FlexConnect mode and must …

LVGL开发教程:二、ESP-IDF 使用CmakeList管理自己的文件以及文件夹

本文需要已经安装了Vscode+IDF插件没有安装的请提前安装一下,IDF插件为乐鑫的插件不需要翻墙。需要环境搭建请看下面链接。 环境搭建: VScode+platformIO和Vscode+ESP-IDF两种开发环境搭建 项目例程下载地址: IDF-CmakeTes,密码:8888 另外,由于你和我的路径不一致,下载的工…

富足金字塔:人的努力是为了扩大选择的范围

人的努力是为了扩大选择的范围&#xff0c;这是熵减的另一种表述。富足金字塔代表着人生的三重境界。第一层是温饱。人需要食物、水、住所。第二层是品质。能源、ICT、教育带来更有品质的生活&#xff0c;如智能门锁、智能马桶、扫地机、洗碗机、洗衣烘衣机。第三层是梦想。包括…

netty群聊系统

1设计思路&#xff1a;启动一个服务端&#xff0c;多个客户端第一个客户端启动时&#xff0c;会告诉服务器上线了第二个客户端启动时&#xff0c;告诉服务器上线&#xff0c;并且通知第一个启动的客户端第三个客户端启动时&#xff0c;告诉服务器上线&#xff0c;并且通知第一个…

应用上架小技能:2.1 蓝牙权限使用说明和5.1.1权限使用说明

文章目录 引言I Guideline 2.1 - Information NeededII Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage引言 App是用来蓝牙进行打印小票,需要提供演示视频摄像头、位置和蓝牙的使用场景需要在应用配置文件Info.plist进行说明。uniapp权限说明配置界面 I G…

利尔达在北交所上市:总市值突破29亿元,叶文光为董事长

2月17日&#xff0c;利尔达科技集团股份有限公司&#xff08;下称“利尔达”&#xff0c;BJ:832149&#xff09;在北京证券交易所上市。本次上市&#xff0c;利尔达的发行价格为5.00元/股&#xff0c;发行数量为1980万股&#xff0c;发行市盈率为12.29倍&#xff0c;募资总额为…

2023情人节正经性生活调研报告

省时查报告-专业、及时、全面的行研报告库省时查方案-专业、及时、全面的营销策划方案库【免费下载】2023年1月份热门报告合集ChatGPT的发展历程、原理、技术架构及未来方向2023年&#xff0c;如何科学制定年度规划&#xff1f;《底层逻辑》高清配图今天给大家带来丁香医生最新…