2023年数据结构串的实验报告.pdf
一火化车工如学院HUBEI UN I VERS I TY O F AUTOMOT I VE TECHNO L 0 G Y数据结构程序设计实验报告0 3实训题目:串的构造与应用(自行编写)专 业:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 软件工程班 级:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 软件 161姓 名:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 王 洋_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _学 号:完毕日期:_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 2023年 11月 5 日2023年 1 1 月实验前提目录错 误!未定义书签。一、1.实验序言错 误!未定义书签。、2.实验目的。错 误!未定义书签。一、3.实验背景 错 误!未定义书签。一、4.。实验方式错 误!未定义书签。程序原理错 误!未定义书签。二、1.,设 计 思 绪。错 误!未定义书签。二、2.实验原理错 误!未定义书签。程序设计错 误!未定义书签。三、1 .重要功能错 误!未定义书签。三、2.程 序 界 面。错 误!未定义书签。四功 能 实 现。错 误!未 定 义 书 签。五四、1 .串的初始化。错 误!未 定 义 书 签。四、2.o串的插入和删除错 误!未 定 义 书 签。四、3.串的修改及提取子串。错 误!未定义书签。四、程 序 调 试。错 误!未 定 义 书 签。四、5.错 误!未定义书签。四、6.要 点 函 数 功 能 源 码。错 误!未 定 义 书 签。程序总结错 误!未定义书签。程序细节五、1.程 序 收 获 清 单。错 误!未定义书签。五、2.程序局限性改善六错 误!未定义书签。实验总结,错 误!未 定 义 书 签。一实验前提一、1.实验序言每一次实验都是一种历练和进步,至少在每次进行序言的时候,都会去总结和想办法改善程序。即使能力有限,我也切身感受到了进步,以及进步后对程序的稍微深度地思考。而这次对于串的实验,显然让我感受到了,这样的思考非常欠缺,我所需要完毕的尚有很多,特别是随着功能的完善,和进一步的编程,会发现其中有更多的地方需要我去改善,特别是功能越多越进一步,这种感觉就越明显一、2.实验目的串的基本操作的编程实现(2学时,验证型),掌握串的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找、合并、剪裁等操作,存储结构可以在顺序结构或链接结构、索引结构中任选,也可以所有实现。也鼓励学生运用基本操作进行一些应用的程序设计。一、3.实验背景在较纯熟的掌握关于对象的编程方法后,这次我就改用了 C+进行编写,并且难度要比我预期的要低,效果反而更好了。同时,串基于字符数组实现要容易得多,并且对于一维数组的具体操作,已经相对较为纯熟,并且也提供了很多关于字符串的相关函数,所认为了提高编程水平,这次对于串的操作渚B不依赖系统函数和字符串函数,相反,进一步初始化,插入,删除,遍历等功能的本质,对字符串的底层进行编程实现。同时也可以使用以前掌握的表格打印方法,让字符串的位置一目了然,同时也方便了字符串的删除和插入等操作。一、4.实验方式本次实验的插入和删除函数的对于长度的判断,我在自行编写的时候出现了错误,所以参阅了课本后对其进行了修改,再者就是如何定一个一个字符串类,其他的所有函数和表格打印输出,界面等都自行编写,并且较以往,有了明显的突破,此外,这次上机是运用类进行的对字符串的编写,以后也会多尝试使用C+进行编写。二程序原理二、1.设计思绪本次实验与以往有很多不同,一方面就是在可以移植的界面和函数外,其他的 都 改 用C+进行编程,并用类实现了字符串。另一方面,就是在编程过程中,随着功能和函数实现的进一步,我发现了越来越多的问题,并对其进行了改正,而在改正过程中进行进一步思考,又发现了更多的问题,这些问题本领不是程序的问题,也不是函数错误,而是功能上的缺陷和隐患。与以往的写完就没其他重大问题不同,这次的编写的确可以发现很多之前没有也无法注意到的问题,所以一直尽自己的努力在改善。以下是本次两个程序的设计图。基于类进行功能实现拷贝框架和界面改用C+实现修改调试多次优化输出打印图1 一 程序设计流程图二、2.实验原理串的基本功能实现依旧是基于字符数组,且对串的操作也是对数组的操作,而对数组基本的操作,一方面就需要对数组进行初始化。而串的插入和删除等操作,由于用户的不可预见性,所以操作的长度需要提前进行解决,插入多少位置就需要把插入位置的右端所有的数据进行移动,而删除指定两端位置的字符串,与插入实现方法无异,这都会导致大量的移动,因此内部解决操作工程量巨大,并且效率不高,即使链表可以轻松解决这个问题,但对于串的特殊性,它在这里的作用反而是它最大的弊病,因此相比之下,数组在一定限度上反而要比链表容易设计和操作。修改功能则需要考虑的更多,一般分为三种情况:1.只修改一个字符,直接找到位置进行修改;图 2 一修改字符数短于指定位置长度的操作示意图3.修改字符数长于指定位置长度,需要修改替换指定长度,然后移动指定右端位置的后面的数据,腾出剩下需要修改的字符空间,最后进行写入即可。具体的操作示意图如下图3。(4)写入剩余修改字符图3 一 修改字符数长于指定位置长度的操作示意图总体来看,数据的移动量太大,效率不高,但是可以保证操作的逻辑性和对的性,在编程实现方面也简朴了许多。三程序设计三、1.重要功能串可以实现的功能很多,但是作为一个设计者,有时候可以优化一些方案,把功能结合起来,用一个部分实现一些功能,比如我把数据的打印显示做的人性化,在某些方面来说,简化了数据求长,子串的搜索,当然,这些考虑,只是基于较短的数据输入条件,并不可取。一般的功能即新串插入、旧串删除、当前串遍历、当前串求长度、求指定位置子串。但是将遍历和求数据长度单独提取出来作为一个功能觉得不合适,于是,程序整体是在每次操作前后,都进行一次遍历,在使用功能前后都可以让用户清楚地读取当前串情况。(1)初始化串内容,并自动获得串长(2)串插入、删除、修改(3)获得子串(4)串长度以及遍历三、2.程序界面串的实现界面沿袭了之前的实验界面,并且将用户输入,和计算机提醒都锁定在了两行之内,保证表格的对的打印。输入输出方格下面是数据和数据表格显示的区域,具体如下图。软件161-19-王洋-申的储存操作1.初始化字符串2.插入新字符串3.删除指定字符4.修改指定字符5.遍历此字符串6.显示串长7.提取子串8.修改表格9.退出系统请输入功能:图4 一串的简朴操作程序界面图四功能实现四、1.串的初始化串的实现改用类进行实现,所以在构造函数内只对串就行动态内存获取,以及长度归零。同时为了能多次进行初始化,在每次拟定长度以前,对长度进行归零操作。串内容的获取,采 用g e t char函数进行缓存区读取,保存回车,和空 格 在 读 取 到 字 符 时,结束循环。这个地方我当时有一个疑问就是,我在动态内存分派的时候,故意使用1长度,发现仍然可以进行任意长度的输入,并且操作去除长度判断,其他的函数都是可以运营的。这让我非常疑惑,疑惑在动态内存分派到底起到作用没有?之后和吴贝贝同学讨论发现,循环获取字符的操作中,我直接对内存进行了访问和操作,所以动态内存申请就显得没有作用了,并且也没有必要。但是仔细想后有发现,目前我们对操作系统如何分派内存的机制不是很了解,假如当我们在进行循环访问和操作内存的时候,一连串的内存的某个地方出现了其他程序使用的区域,那么循环到下一个正在使用的区域,就会打破此外一个程序的内存访问区,也许会导致其他程序的崩溃,但是后来查询资料发现,内存的分派,系统都会自动对的地选取一系列连续的可用内存给程序使用,所以不必要考虑到会破坏其他程序的内存区域。但是这只是小部分的获取字符串内容,假如碰到大量的字符需要输入,就必须要考虑到这个问题,毕竟对一个连续的内存区域进行操作,难免会出现错误这些问题,不仅让我进一步体会到编程中我们没有考虑过的问题,也让我意识到,我们思考的主线不够,此后的实验中,以后的编程里,还需要考虑更多更多,以下是初始化函数代码。v o i d s t r i n g::s t r C r e a t e()(。i n t i=0;l e n g th=0;/可多次进行输入3 g e t c h a r ();/吃掉选择功能的回车。w h i l e (s t r i =g e t c h a r ()!=|s t r i +1 =N U L L)/不是继续获得字符。由于对内存进行操作需要保证下一个内存空。i+;当 然 s t r i +1 =N U L L 这个我不能保证真正能用上或是自身就是个错误 1 e n g t h =i ;)四、2.串的插入和删除插入插入部分,获得插入位置,同时输入插入内容,通过插入的内容判断长度,并把这些参数传入设立好的成员函数,并给对象发消息,进行插入操作。本质上也就是通过插入内容的长度来进行原串的移动,然后进行数据写入。当然,由于我设立了可以保存空格和回车,特别是回车,并且将其遍历内容打印到表格中,在某些情况下会犯错。比如假如字符串内有了回车,我的打印内容会在表格内也会换行,这样观测字符串长度就会犯错(在表格上看)由于表格上的空位置,在串内是不存在的,如下图,这样就对复杂的插入操作,就需要更复杂的输出打印方式,所以程序需要考虑,可以进步的地方的确很多。请输入需要插入的位置:14123456789 10123451ABC11图5-输入需要插入的位置未初始化或输入的位置有误!请按任意键继续.图6由于长度问题和表格会提醒错误(2)删除删除功能同样是数据的移动,用户输入需要删除的左右位置,就可以通过字符的移动来实现。和插入功能有着相同的问题,就是带有回车的部分不好解决,重要是由于我加入了表格打印,这个打印限制了我不少发挥的地方,但是它的确又好用,所以目前的我不能两全其美,也需要反省和进一步学习。对于普通的删除操作基本没有多大问题,如下图演示。图7一 输入所需要删除的位置请输入功能:2 3 4 5 6 7 8 9 1 0图8一成功删除指定位置内容四、3.串的修改及提取子串删除,如实验原理所述,这里不再具体阐述,重要存在一些仍由于打印表格出现的问题,就是修改带回车内容的字符串,修改后打印出来的内容会不好解决,不带回车的是没有问题的,由于变化性太大,所以不好把控,如下图,我在当前串内对4 和 5 直接的位置进行修改,回车确认后如下显示。请 输 入 串,以回车结束!2323456789 10图9一修改错误范例请输入功能:23456789 10图1 0 一 回车后显示错乱(2)获得子串,原理与删除相同,函数内得到位置之后返回一个新的数组指针,然后对其输出显示即可,同时尚有显示长度,当然由于回车和空格的存在,并且回车符号虽然可以用其他的符号显示出来,代替看不见的回车或者空格,但是这样的替代系统不认可,显示不出来,所以也移除了这个功能,导致假如串内有回车或者字符,字符长度和肉眼看到的不同样。四、4.程序调试程序功能实现后,进行了大量的改善具体如下。(1)该用表格打印,方便观看。(2)加入初始化含回车,重新考虑输出打印。(3)加入获得子串功能。(4)在输出打印的部分,调试了很久,为了保证每一行被输满,并且要考虑到回车的效果,改善了很多,同时也加入了可以修改表格的长和宽的效果。四、5.程序细节(1)运用类实现串的操作。(2)使用了制表符制作表格,让输入打印更美观。运用光标定位,让用户输入和输出提醒被锁定在一个区域内,不仅方便观看和操作,也保证了表格的安全和完整。(4)加入回车和空格输入,让输入变得灵活。(5)将一些语句很短的判断性质的函数融合在一起,并使用了重载。四、6.要点函数功能源码打印输出串(遍历)源码。v o i d stri n g:strTravers e()i n t i,j;i n t i tem;增长中间变量,防止i 被修改f o r(i =0,j =0,i tem =0;i l en g t h -1;i+,i tem+)最后一个字符单独判断(di f (i !=0&i%co l um n =0|s tr i =n )需要分情况d 63i f (st r i 二 二 )。(。i+;直接换行,跳过回车字符i tem =0;当碰到回车,需要返回左边进行打印。j+;i t e m=0;当碰到整行,需要返回左边进行打印。)。Sc t Po s(3 +3 *i tem,1 6 +j *2);。s td::co u t stri;)。0 i f (s trl en g th-l 二 二 一)/假如最后一行只有结束符 那么不让它显示s。std:c o u t s t d::en dl;。el s e/假如不是就把它打印出来SetPo s(3 +3*i tem,1 6 +j *2);s std:co u t s tr i ;0 std:co u t s td:e n d 1;。Set Po s(l,1 1);五 程序总结五、1.程序收获清单(1)改用类进行编写,效果和收益都不错。(2)进一步功能,考虑的多了,会发现更多的进步空间,会重要更多的程序细节,特别是在打印输出部分,我至少改善了六次(如要点功能代码)。(3)精简功能函数,避免在函数中出现输入输出。(4)函数多使用了返回值,增长可用性,精简了函数的外部。五、2.程序局限性改善(1)类的使用需要更加纯熟。(2)表格的使用仍然是一个弊端,需要考虑其他的美观界面。(3)程序实现功能较少,增长功能由于打印表格而维护起来很麻烦,以后想办法学习更好的输入表格形式。(4 )由于加入了表格,打印起来非常复杂并且容易犯错,重要因素是计算方法的问题。并且由于功能的增长,会越来越麻烦,并且增长犯错概率(不是指程序自身犯错,而是打印的时候会犯错)。(4)获得老师指导,点出我的函数内出现了常量,函数内仍然使用了常量,不方便修护,以后会多注意。六实验总结实验用类很好的实现了很多功能,并且减少犯错率,增长编写效率。但由于没有好的输出方式,让基于这些功能的输出打印,表现的非常脆弱,并且难以修复,当然这不影响本次实验的重要内容,只是我自己在扩展程序中发现的问题。同时随着问题的进一步,会暴漏更多的问题。同样这也是一次次的成长。最后与吴贝贝同学讨论了对内存的操作的利弊,并帮我解决了其中的部分疑惑,也感谢马老师给予程序中的一些建议。