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

1.本周学习总结

一:对栈和队列的认识:栈:我把栈理解为往一个空间不大箱子里堆东西,最先放进去的只能最后才能拿出来,也就是先进后出。它只能在一端进行插入和删除运算,和对一样是受限制的线性表,运算的一端称为栈顶,向栈中插入元素称为压栈、进栈、入栈,在入栈时,注意是否栈满以及栈满的条件;在出栈时,注意栈是否为空。
二:队列:我们生活中的排队买票也是队列的情况,先买完票的人先走,后面的只能等前面的人买完票了才能买,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。
三:体会:栈与队列所学的内容与之前学的顺序表有相通之处,比较好理解,不过还是有它的难点,把栈和队列结合起来使用有时候我就摸不着头脑。

2.PTA题目

2.1.题目1:6-12 jmu-ds-舞伴问题

假设在周末舞会上,男士和女士们分别进入舞厅,各自排成一队。跳舞开始,依次从男队和女队队头各出一人配成舞伴,若两队初始人数不同,则较长那一队未配对者等待下一轮舞曲。现要求写一算法模拟上述舞伴配对问题。 你需要用队列操作实现上述算法。请完成下面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); //配对舞伴 
Q:队列
e:参加舞会的人
dancer:全部舞者
num:参加舞会的人数
输入说明
先输入参加舞会人数,再分别输入参加舞会人的姓名和性别

输出说明
先输出配对的男女舞伴,若队伍有剩人,则输出剩下人性别及剩下人数目。

输入样例:
6
张1 F
林1 F
王2 M
李1 F
薛2 M
翁1 F
输出样例:
The dancing partners are:
张1  王2
林1  薛2
F:2

2.1.1代码截图



2.1.2本题PTA提交列表说明

  • Q1:段错误&&编译错误:该题中的求队列长度函数写是错了(我写的是遍历队列,计数i,但没移动指针(也不知道我当时怎么想的),所以当时返回的是错的答案,提交是想看看有哪些测试点。
  • A1:解决办法:while(队!空) + 指针移动+ 计数i++ end。
  • Q2:格式错误:男女舞伴输出输出时中间应有两个空格。
  • A2:看到格式错误,首先查看自己编译器输出和输出样例对比,发现少空格,加上即可。

2.2 题目2:在一个数组中实现两个堆栈

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

函数接口定义:
Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );
其中Tag是堆栈编号,取1或2;MaxSize堆栈数组的规模;Stack结构定义如下:

typedef int Position;
struct SNode {
    ElementType *Data;
    Position Top1, Top2;
    int MaxSize;
};
typedef struct SNode *Stack;
注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop函数必须输出“Stack Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。

输入样例:
5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End
输出样例:
Stack 2 Empty
Stack 2 is Empty!
Stack Full
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11

2.2.1代码截图


2.2.2本题PTA提交列表说明。

  • Q1:答案错误:由于开始不熟悉两个堆栈的的边界,所以在开始设计栈满时我直接让S->TOP1=S->TOP2,导致答案错误。
  • A1:对比网友的答案,同时对准堆栈边界,把S->TOP1+1=S->TOP2即可。
  • Q2:由Q1改出来过了栈满的测试点,随即我看栈空的边界,发现

2.3 题目3:符号配对

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

输入格式:
输入为一个C语言源程序。当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束。程序中需要检查配对的符号不超过100个。

输出格式:
首先,如果所有符号配对正确,则在第一行中输出YES,否则输出NO。然后在第二行中指出第一个不配对的符号:如果缺少左符号,则输出?-右符号;如果缺少右符号,则输出左符号-?。

输入样例1:
void test()
{
    int i, A[10];
    for (i=0; i<10; i++) /*/
        A[i] = i;
}
.

输出样例1:
NO
/*-?
输入样例2:
void test()
{
    int i, A[10];
    for (i=0; i<10; i++) /**/
        A[i] = i;
}]
.

输出样例2:
NO
?-]
输入样例3:
void test()
{
    int i
    double A[10];
    for (i=0; i<10; i++) /**/
        A[i] = 0.1*i;
}
.

输出样例3:
YES

2.3.1设计思路

main函数:
① 处理遇到  .   号结束。
②遍历字符数组,遇到符合的左括号则入栈,特殊处理  /* ,遇到/* 则换为 <  来入栈,但要多移动数组一个。
③处理右括号,若此时的栈顶为与此时的数组元素匹配且栈不为空,则出栈,否则就缺少左括号,注意/* 号时要多走一个。
④设计输出缺少右括号的函数print(),简短代码。
⑤结束遍历字符数组且此时栈为空,则匹配完全。
end ......

2.3.2代码截图





2.3.3提交列表及其说明

  • Q1:编译错误:我使用gets(str)来输入字符,提交试了几次后才发现没有定义gets()的头文件。
  • A1:改为scanf()来输入字符即可。
  • Q2:答案错误:在老师讲了解题思路加上对比同学的代码,我的代码思路没有问题,发现我的答案输出受了上一题的影响写为no
  • A2:正确答案应为NO,改过来即可。

2.4 题目4:报数游戏

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

输入样例:
5 3
输出样例:
3 1 5 2 4
输入样例:
5 6
输出样例:
error!

2.4.1设计思路

①处理退圈人数比总人数多的情况,if(  n<m)   error;
②入队,若队列不空,取队头,入队所取队头,若队头元素与所要退的报数数字相同,则出队。
③控制输出格式。

2.4.2代码截图


2.4.3提交列表及其说明

  • Q1:编译错误。
  • A1:编译器没有调为C++;
  • Q2:部分正确。
  • A2:PTA 还是可以骗骗分的,过了如果if( m>n) printf("error!");的测试点。这道题还是就是出队入队的操作,经同学的点播后就写出来了。

3、栈和队列上机考试

3.1.1题目

两端分别是一条入口(Entrance)轨道和一条出口(Exit)轨道,它们之间有N条平行的轨道。每趟列车从入口可以选择任意一条轨道进入,最后从出口离开。在图中有9趟列车,在入口处按照{8,4,2,5,3,9,1,6,7}的顺序排队等待进入。如果要求它们必须按序号递减的顺序从出口离开,则至少需要多少条平行铁轨用于调度?

输入格式:
输入第一行给出一个整数N (2 ≤ N ≤10
​5
​​ ),下一行给出从1到N的整数序号的一个重排列。数字间以空格分隔。

输出格式:
在一行中输出可以将输入的列车按序号递减的顺序调离所需要的最少的铁轨条数。

输入样例:
9
8 4 2 5 3 9 1 6 7
输出样例:
4
  • 说明:考试时时间急这道题来不及做,所以没有错误的代码,我就直接贴正确代码叭

3.1.2代码截图(数组做法)


(set做法)

  • 体会:在考试时结束后我在次看到这道题,我的想法是把保证轨道上的列车序号的前者比后进的小,后来发现我想反了,应该是前者比后进的大,这样才可以保证列车序号递减输出,思路清楚后就是实现了,我开始想用队列来做,但是想不到该如何记录增加的轨道数目,于是我就上网查到数组做法,觉得比较好理解,就按照数组做法做了一遍,之后在看到用set来做,emmmmm......果然代码很简洁,值得学习。

3.2.1题目:银行业务队列简单模拟

设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序列。假定不考虑顾客先后到达的时间间隔,并且当不同窗口同时处理完2个顾客时,A窗口顾客优先输出。

输入格式:
输入为一行正整数,其中第1个数字N(≤1000)为顾客总数,后面跟着N位顾客的编号。编号为奇数的顾客需要到A窗口办理业务,为偶数的顾客则去B窗口。数字间以空格分隔。

输出格式:
按业务处理完成的顺序输出顾客的编号。数字间以空格分隔,但最后一个编号后不能有多余的空格。

输入样例:
8 2 1 3 9 4 11 13 15
输出样例:
1 3 2 9 11 4 13 15
  • 说明:这道题在平时做的PTA,由于本人lan,在上机考试前就没做,之所以把它挑在这里说明顺便把自己挂出来 ,是想提醒自己以后不要抱侥幸心理。

3.2.2代码截图



  • 体会:这道题在考后再看时就不觉得难了,与舞伴那道有相似之处,还是出队入队的操作,难做的点是如何实现A的速度是B的两倍的问题,一开始我是不知道如何处理这个问题的,后来看了同学的代码才知道只需要做两次出队入队就可以了。

原文地址:https://www.cnblogs.com/ttyppt/p/10738998.html