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

1.本周学习总结

本周对栈和队列进行了学习,就总体而言,难度不大。通过课本上对于栈和队列的基本操作函数的学习,不仅学会了如何入栈出栈、入队出队,而且了解了栈空、栈满的条件,并了解了共享栈、链栈、循环队列......等更深入的知识。有过之前对于顺序表的学习,这些都还是比较简单的。当然,无论是栈的后入先出还是队列的先入先出,需要对栈和队列的概念的理解要深刻,有同学这么和我说道,栈就像是一个单向开口的羽毛球桶,放球进去,取球出来,栈的后入先出就再也不会忘记了;而队列更简单,队列就像是生活当中的队伍一般,又或者,理解为水管,水流的流向就是那样,水先入先出......我觉得这样的描述很形象,有可取之处,哈哈。再之后就是对于c++的stl容器的使用了,目前接触到了stack(栈)和queue(队列),这两种模板很实用,但第一次使用的我还是掉入了一些初学者容易犯的错误中去。问题一:在调用模板的函数时没有加括号,如要对栈s调用pop函数,写成了s.pop,导致程序崩溃,直接报错了,如图一、二;问题二:在调用pop函数时,缺乏对是否栈(队列)是否为空的判断,导致程序奔溃,如图三。这些问题注意之后,对这些模板的应用基本没什么问题,无非就是缺解决问题的思路了。

2.PTA实验作业

2.1.题目1:题目名称

6-2 在一个数组中实现两个堆栈 (20 分)
本题要求在一个数组中实现两个堆栈。注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop函数必须输出“Stack Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。

2.1.1设计思路

函数题思路不写啦......这里丢一下Operation GetOp(); /* details omitted */函数和void PrintStack( Stack S, int Tag ); /* details omitted */函数,当时用来测试数据时保留下了......有需要的可以拿去试试pta测试数据。

Operation GetOp()
{
	Operation c;
	char a[5];
	scanf("%s", a);
	if (!strcmp(a, "Push"))
		return push;
	else if (!strcmp(a, "Pop"))
		return pop;
	else if (!strcmp(a, "End"))
		return end;
}
void PrintStack(Stack S, int Tag) 
{
	int i;
	switch (Tag)
	{
		case 1:
			printf("Pop from Stack 1:");
			for (i = S->Top1; i >= 0; i--)
			{
				printf("%d ", S->Data[i]);
			}
			printf("\n");
			break;
		case 2:
			printf("Pop from Stack 2:");
			for (i = S->Top2; i <= S->MaxSize-1; i++)
			{
				printf("%d ", S->Data[i]);
			}
			printf("\n");
			break;
	}
}

2.1.2代码截图

2.1.3本题PTA提交列表说明。

  • 问题一:第一次提交错误是因为在判断栈满时出现了疏忽如图:

    写成了:
  • 问题二:这里有一个隐藏的问题,极大的影响了上机考试......在后面考试错题详细展开讲。

2.2 题目2

7-3 符号配对 (20 分)
请编写程序检查C语言源程序中下列符号是否配对://、(与)、[与]、{与}。输入为一个C语言源程序。当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束。程序中需要检查配对的符号不超过100个。首先,如果所有符号配对正确,则在第一行中输出YES,否则输出NO。然后在第二行中指出第一个不配对的符号:如果缺少左符号,则输出?-右符号;如果缺少右符号,则输出左符号-?。

2.2.1设计思路

首先是建立两个字符串(左符号字符串和右符号字符串,同时左右配对字符在字符串中的位置相同,以便于后面使用string类的find函数来判断符号是否配对)。解决题目的中心思路是,利用c++的栈模板,当遇到左括号时入栈,当遇到右括号时,与栈顶符号配对是否成功(用find函数)。当然要先考虑一些情况,如在栈为空的时候,读取到了右符号(缺乏左符号),或在字符串读取结束时,栈中有多余左符号。本题还要求对注释符号 / * * / 也进行匹配。原思路是头铁地连续判断两个字符来判断是否是 / *或者 * /,之后再把/当作左符号(可入栈),匹配时与 * / 进行匹配。但这种处理方式存在严重的短板,即在遇到连续两个左注释符、连续两个右注释符等情况时,可能会导致 / / 反复读取,如连续两个左注释符应该读为两个左注释符,而容易误读为两个左注释符和一个右注释符,导致出错。改进方向——>在输入字符串后,直接对题目中的注释符进行预处理(**将 左注释符和 右注释符转化为<>,同时放入左右符号字符串中一并用find函数来判断),而不是在判断时下大功夫。

2.2.2代码截图


2.2.3本题PTA提交列表说明。

2.3 题目3

6-12 jmu-ds-舞伴问题 (20 分)
假设在周末舞会上,男士和女士们分别进入舞厅,各自排成一队。跳舞开始,依次从男队和女队队头各出一人配成舞伴,若两队初始人数不同,则较长那一队未配对者等待下一轮舞曲。现要求写一算法模拟上述舞伴配对问题。 你需要用队列操作实现上述算法。请完成下面5个函数的操作。先输入参加舞会人数,再分别输入参加舞会人的姓名和性别,先输出配对的男女舞伴,若队伍有剩人,则输出剩下人性别及剩下人数目。函数接口定义:int QueueLen(SqQueue Q);//队列长度 、int EnQueue(SqQueue &Q, Person e);//加入队列 、int QueueEmpty(SqQueue &Q);//队列是否为空 、int DeQueue(SqQueue &Q, Person &e);//出队列 、void DancePartner(Person dancer[], int num); //配对舞伴

2.3.1设计思路

先把所有参加晚会的人分为男队Mdancers和女队 Fdancers,分队结束后,男队女队再同时各出队一人男女配对,直至至少有一队没人,操作结束后有两种情况,两队均结束,无人多余;或有一队剩余,在main函数中题目自带处理,无需再处理......有点像以前的二路归并的方法,同时从两串数据中取一个数据,直至一方结束,再对剩下的数据进行输出处理。

2.3.2代码截图


2.3.3本题PTA提交列表说明。

  • 问题一:错用c++语法,没有仔细看题目的头文件。
  • 问题二:测试数据居然要求在男性和女性名字间有两个空格......被坑了¥*@#&%#$‖<&>

2.4 题目4

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

2.4.1设计思路

n个人从1开是编号,即人的编号为1到n。本题的中心解题思路为,用一个名为i的变量来充当个人所报的数,当i达到题目要求的数m(即这个人应该出队),再将i归零(出队者的下一个人从0开始继续报数)。持续此操作直到队伍只剩一人。

2.4.2代码截图

2.4.3本题PTA提交列表说明。

  • 问题一:......真不是故意的......要求队列要有编程题,两题都是这样的......先这样,等后面的打完了再看看改。

3、栈和队列上机考试

这次上机考不理想,首先选择题开始就没做好,其次主要是在一题做过的题目上花了大量的时间(遇到了以前从来没有遇到过的问题报错)折腾太久了以至于后面的题目都没打,所以这里的错题就选择那题苦恼了很久的题目和选择题。

第一题:选择题错题

第二题:6-2 在一个数组中实现两个堆栈 (20 分)

首先看看我在原题集的提交列表:

再看看我在考试的时候的提交列表:

这题出错的心理原因有两个,第一个问题是在原题集做的时候较为顺利,所以不知不觉中直接过了所有的点,没有理解透彻题目,稀里糊涂,很有自信开考五分钟就打出来了,但是过不了......;第二个问题是,首次见到了输出超限这个错误点,在考试时突然见到这个很懵逼,慌乱了。
这题的真正原因在于,在判断栈满时应该分开判断,而不是同时判断!
错误代码如下:

应该改成这样:

  • 后续需要改进的地方:遇到未见过的问题,应该冷静分析,而不是慌乱不知所措。其实有时候,一些小问题一下子想不出来,应该先打其他题目冷静一下,再回过头来看。
posted @ 2019-04-21 12:13  super饭团君  阅读(944)  评论(0编辑  收藏  举报