一.实验目的:
了解栈和队列的逻辑结构和基本操作,实现栈和队列的基本功能。
通过实验进一步理解栈和队列的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。
二.实验内容:
题目:模拟停车厂管理
问题描述:
设停车厂只有一个可停放5辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达的先后顺序依次排列,若车场内已停满几辆汽车,则后来的汽车只能在门外的便道上等候,一旦停车场内有车开走,则排在便道上的第一辆车即可进入;当停车场内某辆车要离开时,由于停车场是狭长的通道,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门后,为它让路的车辆再按原次序进入车场。在这里假设汽车不能从便道上开走。
基本要求:
以栈模拟停车场,以队列模拟车场外的便道,按照从终端输入数据序列进行模拟管理。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码以及到达或离去的时刻。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出车辆在停车场内或便道上的停车位置;若是车辆离去,则输出车辆在停车场内停留的时间和应缴纳的费用(1小时以内不收费,1小时以上收费标准为2元/小时,在便道上停留的时间不收费)。栈以顺序结构出现,队列以链表结构实现。
测试数据:
(1)连续有7辆车到来,牌照号分别为JF001、JF002、JF003、JF004、、JF005、JF006、JF007,前5辆车应该进入停车位1-5车位,第6、7辆车应停入便道的1、2位置上。
(2)(1)中的情况发生后,让牌照号为JF003的汽车从停车厂开走,应显示JF005、JF004的让路动作和JF006从便道到停车位上的动作。
(3)随时检查停车位和便道的状态,不应该出现停车位有空位而便道上还有车的情况。
(4)程序容错性的测试,当按键输入错误的时候是否有错误提示给用户指导用户正确操作,并做出相应处理保证程序健康的运行。
三. 实验方案
(一)算法设计思路:
停车场用顺序栈模拟,每一个car代表一个车位,设计一个临时辅助栈临时停靠为要离开的车让路的车。便道由队列模拟。
入车先遍历顺序栈查看是否有空位。若有则进入容错时间与车牌。
出车检查停车场是否有这辆车若有则出车,并写下时间缴费离开,同时查看便道是否有车等待若有则进入,同时入车时间由上次车离开时间为准。
显示依靠顺序栈和临时栈交互时显示各个车辆信息
退出改变flag即可
(二)使用模块及变量的说明(例如结构体的定义、含义)
1、typedef struct car //定义车辆信息
2、typedef struct seqstack //定义停车顺序栈
3、SeqStack* init_SeqStack() //初始化停车栈
4、bool Empty_SeqStack(SeqStack *s) //判断停车场是否为空
5、int Push_SpeqStack(SeqStack *s, Car a) //入栈,进车
6、int Pop_SeqStack(SeqStack *s,Car * a) //出栈,出车
7、typedef struct node //链队结点
8、typedef struct lqueqe //链队指针结点
9、LQueue* Init_LQueen() //初始化链队
10、void In_LQueue(LQueue* q,Car b) //入队,进入便道等待
11、int Empty_LQueue(LQueue* q) //判断便道是否为空
12、int Out_Lqueue(LQueue* q, Car* c) //从便道进入停车场
13、Car RTime(SeqStack* s, Car car); //进车出车容错时间
14、int money(Car car,int car_outTH,int car_outTM);//计算花费
15、Car RName(SeqStack* s, Car car); //容错车牌
四. 实验步骤或程序(经调试后正确的源程序)
#include
#include
#include
using namespace std;
#define MAXSIZE 5
typedef struct car
{
string LicPlate;
int hour;
int minute;
}Car;
typedef struct seqstack
{
Car car[MAXSIZE];
int top;
}SeqStack;
SeqStack* init_SeqStack()
{
SeqStack* s;
s = new SeqStack();
if (s!=NULL)
{
s->top = -1;
return s;
}
else
{
cout << "申请失败";
return 0;
}
}
bool Empty_SeqStack(SeqStack *s)
{
if (s->top == -1)
return true;
else
return false;
}
int Push_SpeqStack(SeqStack *s, Car a)
{
if (s->top==MAXSIZE-1)
{
cout << "停车场满了,便道等待";
return 0;
}
else
{
s->top++;
s->car[s->top]= a;
return 1;
}
}
int Pop_SeqStack(SeqStack *s,Car * a)
{
if (s->top==-1)
{
cout << "停车场空了";
return 0;
}
else
{
*a = s->car[s->top];
s->top--;
return 1;
}
}
typedef struct node
{
Car car;
struct node* next;
}QNode;
typedef struct lqueqe
{
QNode* front;
QNode* rear;
}LQueue;
LQueue* Init_LQueen()
{
LQueue* q;
QNode *p;
q = new LQueue();//申请头尾指针结点
p = new QNode();
q->front = p;
q->rear = p;
return q;
}
void In_LQueue(LQueue* q,Car b)
{
QNode* p;
p = new QNode();
p->car = b;
p->next = NULL;
q->rear->next = p;
q->rear = p;
}
int Empty_LQueue(LQueue* q)
{
if (q->rear == q->front)
return 1;
else
return 0;
}
int Out_Lqueue(LQueue* q, Car* c)
{
QNode* p;
if (Empty_LQueue(q)== 1)
{
cout << "便道没车了";
return 0;
}
else
{
p = q->front->next;//p指向的是第一个元素
q->front->next = p->next;
*c = p->car;
free(p);
if (q->front->next == NULL)
{
q->rear = q->front;
}
return 1;
}
}
Car RTime(SeqStack* s, Car car);//容错时间
int money(Car car, int car_outTH, int car_outTM);//计算花费
Car RName(SeqStack* s, Car car);//容错车牌
int main()
{
bool flag = true;//停止标志
string name[5];
int i = -1;//车的辆数
int n;//选项按钮
SeqStack *s,*L;
LQueue* q;
s = init_SeqStack();
L = init_SeqStack();
q = Init_LQueen();
while (flag)
{
cout << endl;
cout << "*******进车(1)*******" <> n;
switch (n)
{
case 1: //进车
{
Car car;
cout << "请输入车辆信息:" << endl;
cout << "车牌:";
cin >> car.LicPlate;
car = RName(s, car);
if (s->top == MAXSIZE- 1)
{
cout << "停车场满了,"<>car.hour;
cout << "mintue=";
cin >> car.minute;
car=RTime(s,car);//时间容错
Push_SpeqStack(s, car);
i++;
cout << endl << endl;
}
break;
}
case 2://出车
{ Car car1,car6;//来出栈入栈中间变量
Car car8;//出车的容器
Car car5;//存储出车时间
int car_outTH;//记录离开时间
int car_outTM;
int top1 = s->top;//存储栈顶下标
int top2;//存储找到的车牌下标
int cost;
cout << "请输入出车车牌:" << endl;
cin >> car1.LicPlate;
//寻址车辆
while (top1 != -1)
{
if (s->car[top1].LicPlate == car1.LicPlate)
{
break;
}
top1--;
}
if (top1 == -1)
{
cout << "停车场没有这辆车";
}
else
{
top2 = top1;
top1 = s->top;
while (top1 != top2)
{
Pop_SeqStack(s, &car1);
cout << car1.LicPlate << "让路" << endl;
Push_SpeqStack(L, car1);
top1--;
}
Pop_SeqStack(s, &car8);//出栈的车走了
i--;//花名册-1
while (L->top != -1)//回栈
{
Pop_SeqStack(L, &car6);
Push_SpeqStack(s, car6);
}
cout << "请输入" << car8.LicPlate << "离开时的时间";
cout << endl<< "hour:";
cin >> car_outTH;
cout << "minute:";
cin >> car_outTM;
cout << endl<top!=-1)//逐个拿出放在临时栈
{
Pop_SeqStack(s, &car2);
cout << "车牌 :";
cout << car2.LicPlate<top!=-1)//逐个拿出放在临时栈
{
Pop_SeqStack(L, &car2);
Push_SpeqStack(s, car2);
}
break;
}
case 4://退出
{
flag = false;
break;
}
default:
cout << "无效功能号,请重新输入";
}
}
}
Car RName(SeqStack* s, Car car)
{
int top = s->top;
while (top != -1)
{
if (s->car[top].LicPlate!=car.LicPlate)
{
//continue 直接出循环了,陷入了死循环;
top--;
}
else
{
cout << endl;
cout << "车牌重复,请重新输入";
cin >> car.LicPlate;
top = s->top;
}
}
return car;
}
Car RTime(SeqStack *s,Car car)
{
int top = s->top;
if (car.minute>=0 && car.minute <= 60)
{
while (top != -1)
{
if ((s->car[top]).hour <= car.hour)
{
if (s->car[top].hour == car.hour && s->car[top].minute < car.minute)
{
top--;
}
else if ((s->car[top]).hour < car.hour)
{
//continue 直接出循环了,陷入了死循环;
top--;
}
else
{
cout << endl;
cout << "时间输入错误,请重新输入:";
cout << endl << "hour=";
cin >> car.hour;
cout << "mintue=";
cin >> car.minute;
top = s->top;
}
}
else
{
cout << endl;
cout << "时间输入错误,请重新输入:";
cout << endl << "hour=";
cin >> car.hour;
cout << endl << "mintue=";
cin >> car.minute;
top = s->top;
}
}
}
else
{
cout << endl;
cout << "时间输入错误,请重新输入:";
cout << endl << "hour=";
cin >> car.hour;
cout << "mintue=";
cin >> car.minute;
top = s->top;
}
return car;
}
int money(Car car,int car_outTH, int car_outTM)
{
int time1=0,time2=0,time3;
int cost;//花费钱财
time1 = car_outTH * 60 + car_outTM;
time2 = car.hour * 60 + car.minute;
time3 = time1 - time2;
if (time3 <= 60)
{
cost = 0;
}
else
{
time3 = time3 / 60;
if (time3 % 60 != 0)
{
time3++;
}
time3--;
cost = time3 * 2;
}
return cost;
}
五.程序运行结果(程序运行结果的一些截图)
六.实验总结(调试过程中遇到哪些问题,怎么解决的)
问题一:每次输入车牌就会报错,引发了异常: 写入访问权限冲突。 **_Left** 是 0xCDCDCDCD。
之后求助CSDN发现是malloc函数的问题发现malloc只能输入一个数据,如果再继续输入下一个,就会异常报错,malloc那样定义是无法给你足够的分配空间存储1个以上的数据的,博主给的提议是换成new果然就不报错了。
问题二:栈顶车辆的时间总是改变,正常输入时间没问题但一旦有错误时间输入栈顶的车辆信息时间就变了
之后我在挪车出栈入栈的时候加入时间查看时间是在什么时候该变的,后来发现入栈后时间是正确的,??后来我取看时间容错,找了半天还是没问题,之后猛然想到时间总是hour变化minute并不变我仔细观察后发现,应该是双==我写成了单=。
问题三:输入第一辆车没问题,输入第二辆车牌就卡住了
我从输入车牌开始一步步捋顺,发现车牌容错出了问题,continue
之后有一个top--,但continue之后的语句就不会在执行了导致top一直不变陷入while的死循环.把top—放continue前面就好了