DS博客作业03--栈和队列

1.本周学习总结

  • 本章主要学习了栈和队列的相关知识,从组成元素的逻辑关系看,栈和队列都属于线性结构。栈是一种只能在一端进行插入或删除操作的线性表,其特点是“后进先出”;而队列只允许在表的一端进行插入操作,在表的另一端进行删除操作,其特点是“先进先出”。栈就像篮子,先往里放东西只能压底,后放的就能先拿出来;而队列就像排队,先到的人可以先走,后到的人只能排在最后。由队列派生的数据结构还有循环队列、双端队列,正是两种限制条件产生的特殊性,才使得在运用时能高效地处理问题。栈应用在简单的表达式求值和迷宫问题,而队列应用在报数问题和迷宫问题。虽然都能解决迷宫问题,但栈的解法只是其中一种,而队列的解法一定是最优解。
  • 虽然用途广泛,但栈和队列的函数定义是比较麻烦的,需要定义多个处理操作,这就需要我们学习c++的stl容器的使用了。头文件为栈和队列,其中自带的一些操作函数十分实用,方便我们设计程序。还有符号配对的题目时,find函数的应用也能简化配对的步骤。所以在学习新的知识时,不能只是局限于书上的知识,还需要通过在网上找一些小技巧,能让我们在解决问题的时候技高一筹,处理得更加轻松。

2.PTA实验作业

2.1.题目1:在一个数组中实现两个堆栈

本题要求在一个数组中实现两个堆栈。

2.1.1设计思路

  • 实现在一个堆栈的数组中,从头和从尾分配两个堆栈,需要进行分类讨论。在C语法中定义栈时,需要注意加上强制类型转换进行定义。先判断要使用的是哪个栈,再进行那个栈的处理,两个栈独立,这个过程不涉及另一个栈,故采用if-else的语句来区别两个栈。其中栈满的情况只有一种,就是两边数据碰撞的时候,即前面的栈顶加一等于后面的栈顶,可以一起判断;而栈空的情况有两种,就需要分两种情况判断,第一种是栈顶指针为-1,第二种是栈顶指针为数组尾。

2.1.2代码截图

2.1.3本题PTA提交列表说明


Q1:刚开始的时候题意不是很理解题意,不清楚两个堆栈到底怎么分配
A1:后来细想堆栈的特点就是堆栈数组有两个方向,但只需要一个插入点,故理解一边一个堆栈的设计方法。
Q2:答案错误的原因是,在先移动指针还是先修改数据的顺序选择上需要进行仔细思考
A2:自加和自减能更简便地表达出指针和数据的改动,方便处理返回数据时先返回后移指针的这种情况。

2.2.题目2:舞伴问题

假设在周末舞会上,男士和女士们分别进入舞厅,各自排成一队。跳舞开始,依次从男队和女队队头各出一人配成舞伴,若两队初始人数不同,则较长那一队未配对者等待下一轮舞曲。现要求写一算法模拟上述舞伴配对问题。 你需要用队列操作实现上述算法。请完成下面5个函数的操作。

2.2.2代码截图

2.2.3本题PTA提交列表说明


Q1:前四个函数为简单的队列操作,故可以用一条语句完成
A1:在函数返回数据时采用返回算式的写法,可增加代码的简洁性,编译错误就是出现在整理代码的时候。
Q2:同时处理两个队列配对问题时,需要设置好配对结束的终止条件
A2:分步处理两种不同结果,当任一队列为空时结束配对循环,并将非空的队列数据返回。

2.3.题目3:符号配对

请编写程序检查C语言源程序中下列符号是否配对://、(与)、[与]、{与}。

2.3.1设计思路

  • 要求检查一段代码中左右符号需要进行配对,最近的括号间进行配对,有一对不正确则代码错误。这类题目处理时,大部分情况每个符号间是独立的,故采用getchar来进行逐一识别,小部分来特殊处理。根据每个右符号与前一个符号进行比较这个特性,我们可以选择“后进先出”的栈进行字符存储。当遇到左括号时符号入栈,当遇到右符号时与栈顶比较,若配对则让栈顶的符号出栈,若不配对则代码错误。
  • 由于其中存在一组特殊的左右符号为“/”和“/”,它们由两个字符组成,所以判断时需要多读取下一个符号才能完成配对。同样的,’.‘不能代表代码结束,只有当读到只有一个句点’.‘和一个回车的时候,才标志着输入结束,故也要多读取下一个符号。配对时定义字符串、字符数组和运用find函数都能使代码更加简洁易懂。

2.3.2代码截图


2.3.3本题PTA提交列表说明


Q1:符号配对失败的情况有多种,需要进行准确的判断
A1:可以通过devc举例模拟,也可以通过直接输入 来对应测试点的要求,可以减少在这方面耽误的时间,这也是我一排“部分正确”的原因。
Q2:一步步修正代码后,最后剩下的测试点是配对完所有代码后有多余左括号的情况
A2:遇到左括号只管入栈,会造成最后虽然正常结束遍历代码但栈中仍有剩余符号,故需要另外进行栈是否为空的判断,若不为空才是配对成功。

2.4.题目4:jmu-报数游戏

报数游戏是这样的:有n个人围成一圈,按顺序从1到n编好号。从第一个人开始报数,报到m(m<n)的人退出圈子;下一个人从1开始报数,报到m的人退出圈子。如此下去,直到留下最后一个人。其中n是初始人数;m是游戏规定的退出位次(保证为小于n的正整数)。要求用队列结构完成。输出数字间以空格分隔,但结尾不能有多余空格。

2.4.1设计思路

  • 题意明确,排到的人若是则退出圈,若不是则继续报数,顺序与“先进先出”相似,所以采用队列解题。设计程序时,报到m的人出队输出,其余的人出队入队,等待下一次报数,直到全员报完。由于m的值会多次循环,所以采用累加取余数的方法替代从一开始。
  • 需要注意的几点是,第一,queue容器定义的队列为动态分配空间,所以不用担心队满的问题,减轻代码量;第二,刚定义队列时队列是空的,所以需要我们自行加入序数作为初始圈;第三,输出时结尾不能有多余空格,所以要用flag区分输出。

2.4.2代码截图

2.4.3本题PTA提交列表说明


Q1:做这道题时思路清晰且用devc处理了编译错误,所以pta上一遍过
A1:queue容器的使用使得队列的应用容易了许多,只要题意理解,这类题目问题不大。

3、栈和队列上机考试

错题一:符号配对

请编写程序检查C语言源程序中下列符号是否配对://、(与)、[与]、{与}。


  • 其实题目的大体已经出现,各类基本处理情况已经完成,但是其他题目的完成得不好加上时间也快到了,所以一些细节来不及想,就剩两步:一个句号加上一个换行符才是代码结束的标志;代码结束要进行最后的栈空判断。
  • 考试时忘记了find函数的用法,便应用了最初我采用的if直接代数到 i 上的方法,这是后续要改进地方。老师讲解的方法是直接字符串读取一行数据,这种方法我不是很熟练,所以没有采用,这也是可以改进的地方。

错题二:表达式求解

输入一个后缀表达式,程序求出表达式值。


  • 考场上来不及看的题目,在回来后解答出来。
  • 本题注意单个字符提取需要将它们组合为一个数,其中减号可能为负数,所以要特殊处理负数;四则运算的处理需要讨论除数是否为0的情况。

案发现场(这段可以选择性忽略)

  • 刚开始时我是选择先手一道编程题来找找感觉,因为编程题就是给我们分配了任务,千方百计只要达到目的就行,有利于找到思考的感觉。但是在20分钟过后打出程序大体却没能成功编译,选择了放弃。转向第一道函数题,原本简单题目编译错误愣是找不出问题,题目的主程序在devC上运行就自带错误导致连调试都做不到,选择了放弃。转向第二道编程题,是一道简单题,虽是原题,但屡次出错的我心态崩溃,怎么做的完全没有感觉。这时的我过了一个小时还没拿到一分。
  • 最重要的还是心态,不停的调整自己的心情,让情绪稳定。将题意反复理解,想起了做题的方法,完成了首杀。再回看函数题,仔细看了每个字符才发现问题,因为没有分清S的大小写所以指针错误,再做稍微修改就完成了。再看回第一道编程题,发现了栈容器的使用有点奇怪,原来是在用栈的函数时后面要加上括号,后来全加上后对照测试点一步步处理情况,时间也就在这时候结束了,没能完成题目。

体会

  • 做题量太少,解题方法和纠错方式不能很快处理;
  • 专注性不行,在考场上看到题目时思路不能马上明确,导致一段时间的脑子真空期;
  • 题目的取舍很重要,先易后难做题,不能逮住就莽做;
  • 心态的调整很重要,不因题易大意,不因题难放弃。
posted @ 2019-04-21 22:37  不凉々少年  阅读(421)  评论(0编辑  收藏  举报