[问题描述]
设停车场是一个可以停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次有北向南排列(大门在最南端,最先到达的第一车停放在车场的最北端),若车场内已停满n辆车,那么后来的车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。试为停车场编制按上述要求进行管理的模拟程序。
[实现提示]
以栈模拟停车场,以队列模拟车场外的便道。每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码以及到达或离去的时刻。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停车不收费)。栈以顺序存储结构实现,队列以链表结构实现。
#include<cstdio>
#include<iostream>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#include<cstring>
#define price 0.1
using namespace std;
typedef int Status;
typedef int ElemType;
const ElemType Max_n=2;
/*车的信息的结构体的定义*/
typedef struct {
ElemType enterh,enterm,enters;
ElemType outh,outm,outs;
char num[20];
}CarDataType;
/*顺序栈的存储结构*/
typedef struct {
CarDataType *base;
CarDataType *top;
ElemType MaxSize;
ElemType Length;
}SqStack;
/*队列的存储结构*/
typedef struct node {
CarDataType data;
struct node *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
SqStack S; //临时停车场
LinkQueue QA; //便道
SqStack ST; //出停车场时,车辆临时停放点
/*顺序栈的初始化(模拟停车场大小)*/
void InitStack(SqStack &S){
S.base=new CarDataType[Max_n];
if(!S.base) exit(OVERFLOW);
=S.base;
S.Length=0;
S.MaxSize=Max_n;
}
/*队列的初始化(模拟便道和临时停放点)*/
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=new QNode;
Q.front->next=NULL;
}
/*车辆入栈*/
Status Push(SqStack &S,CarDataType e){
if(-S.base==S.MaxSize) return ERROR;
*++=e; return OK;
}
/*入队*/
void EnQueue(LinkQueue &Q,CarDataType &e){
QueuePtr p=new QNode;
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
/*停车场已满,进入便道*/
void EnterQA(LinkQueue &QA,CarDataType &Car){
EnQueue(QA,Car);
printf("车辆进入便道成功,请您继续操作!\n");
}
/*打印便道停车信息*/
void PrintQA(LinkQueue QA){
LinkQueue p=QA;
if(p.front==p.rear){
printf("便道没有车辆!\n");
}else{
printf("便道中车辆的信息!(车牌号,到达时间)\n");
while(p.front!=p.rear){
printf("%s %02d:%02d:%02d\n",p.front->next->data.num,p.front->next->data.enterh,p.front->next->data.enterm,p.front->next->data.enters);
p.front=p.front->next;
}
}
}
/*打印停车场中的元素*/
void PrintS(SqStack S){
SqStack S1=S;
if(S1.base==){
printf("停车场中没有车辆!\n");
}else{
printf("停车场中的车辆信息!(车牌号,到达时间)\n");
while(S1.base!=){
--;
printf("%s %02d:%02d:%02d\n",->num,->enterh,->enterm,->enters);
}
}
}
/*到达的车进入停车场*/
void EnterCarPark(SqStack &S,LinkQueue &QA){
printf("请输入到达车辆到达时间(24小时制)和车牌号(空格区分):\n");
CarDataType Car;
scanf("%d:%d:%d",&Car.enterh,&Car.enterm,&Car.enters);
scanf("%s",Car.num);
if(Car.enterh>=0&&Car.enterh<24&&Car.enterm>=0&&Car.enterm<60&&Car.enters>=0&&Car.enters<60){
if(Push(S,Car)){
S.Length++;
printf("车辆进入停车场成功,并且车停在了%d号车位\n",S.Length);
system("pause");
system("cls");
PrintS(S);
PrintQA(QA);
}else{
printf("停车场已满,请进入便道!\n");
printf("进入便道中ing·····\n");
EnterQA(QA,Car);
system("pause");
system("cls");
PrintS(S);
PrintQA(QA);
}
}else{
printf("时间输入错误,请重新输入正确的时间.\n");
EnterCarPark(S,QA);
}
}
/*出栈*/
Status Pop(SqStack &S){
if(==S.base) return ERROR;
--;
return OK;
}
/*取*****可以最先出来的车辆*/
CarDataType GetStackTop(SqStack S){
if(!=S.base)
return *(-1);
}
/*进入临时停放点*/
void EnterST(SqStack &ST){
Push(ST,GetStackTop(S));
Pop(S);
S.Length--;
printf("\n\n打印进入某辆车临时停车场时,车辆停放情况");
PrintS(S);
PrintQA(QA);
printf("\n\n");
printf("进入临时停放点成功!\n");
}
/*出队*/
void DeQueue(LinkQueue &Q,CarDataType &Car){
QueuePtr p=Q.front->next;//p指向队头元素
Car=p->data;
Q.front->next=p->next;//修改头结点的指针域
if(Q.rear==p)//删除的是队尾元素
Q.rear=Q.front;
delete p;
}
/*临时停放点一次出队栈*/
void OutST(SqStack &S,SqStack &ST){
if(ST.base==)
printf("临时停放点无需使用,默认使用完毕\n");
if(ST.base!=){
CarDataType Car=GetStackTop(ST);
if(Push(S,Car)){
S.Length++;
}
Pop(ST);
OutST(S,ST);
}
}
/*便道一次出队*/
void OutQA(SqStack &S,LinkQueue &QA,CarDataType &Car){
if(QA.front==QA.rear)
printf("由于便道中没有车,所以无需出车(默认进入停车场成功)\n");
if(QA.front!=QA.rear){
QA.front->next->data.enterh=Car.outh;
QA.front->next->data.enterm=Car.outm;
QA.front->next->data.enters=Car.outs;
if(Push(S,QA.front->next->data)){
S.Length++;
}
DeQueue(QA,QA.front->next->data);
if(S.Length!=Max_n)//栈未满,便道继续进
OutQA(S,QA,Car);
}
}
/*拿到队头元素*/
CarDataType GetTop(SqStack &S){
return *(-1);
}
/*找到对应的车*/
Status GetObCar(SqStack &S,CarDataType &Car){
//printf("GetTop(S).num=%s\n",GetTop(S).num);
//printf("Car.num=%s\n",Car.num);
if(GetTop(S).num[0]==Car.num[0])
return OK;
else{
EnterST(ST);
GetObCar(S,Car);
}
return OK;
}
/*离开停车场,目前只支持当天离开停车场,找到需要出去的车,并且此车一定存在,
他后面的车进入临时停放点, 待车出去后,临时停放点车进入停车场,便道有车时也进入停车场(此时
便道的车的进入时间就是开始计费的时间),直到停车场满.
*/
void OutCarPark(SqStack &S,SqStack &ST){
printf("\n***********打印完整的停车情况*************\n");
PrintS(S);
PrintQA(QA);
printf("********************************************\n\n");
//输入时间需要大于到达时间
printf("请输入离开车辆离开时间(24小时制)和车牌号(空格区分):\n");
CarDataType Car;
scanf("%d:%d:%d",&Car.outh,&Car.outm,&Car.outs);
scanf("%s",Car.num);
if(Car.outh>=0&&Car.outh<24&&Car.outm>=0&&Car.outm<60&&Car.outs>=0&&Car.outs<60){
if(==S.base) exit(OVERFLOW);
//printf("%s\n",(GetTop(S)).num);
//printf("%s\n",(Car.num));
if(GetObCar(S,Car)){
//计算您应该交付的费用
double Stime=GetTop(S).enterh*3600+GetTop(S).enterm*60+GetTop(S).enters;
double Etime=Car.outh*3600+Car.outm*60+Car.outs;
printf("您需要交付的金额为:%.2lf\n",(Etime-Stime)*price);
}
//找到该车开出停车场
if(Pop(S)){
S.Length--;
printf("PS:经过一番周折,车终于开出!临时停放点可进入,便道可进入\n");
printf("\n***********所有车未进入前停车情况***********\n");
PrintS(S);
PrintQA(QA);
printf("********************************************\n\n");
OutST(S,ST);
printf("临时停放点车使用完毕!\n");
if(S.Length!=Max_n){
OutQA(S,QA,Car);
printf("便道的车进入停车场成功!\n");
}
printf("\n***********所有操作后停车情况***************\n");
PrintS(S);
PrintQA(QA);
printf("********************************************\n\n");
}
}else{
printf("时间输入错误,请重新输入正确的时间.\n");
OutCarPark(S,ST);
}
system("pause");
system("cls");
}
void SystemMenu(SqStack &S,LinkQueue &QA,SqStack &ST){
printf("***********欢迎进入×××停车场系统***********\n");
printf("***********1.车辆进入*************************\n");
printf("***********2.车辆离开*************************\n");
printf("***********3.查询便道停车信息*****************\n");
printf("***********4.查询停车场停车信息***************\n");
printf("***********5.退出系统*************************\n");
printf("请输入您的选择:");
Status chose;
cin>>chose;
switch(chose){
case 1:{
EnterCarPark(S,QA);
SystemMenu(S,QA,ST);
}
case 2:{
OutCarPark(S,ST);
SystemMenu(S,QA,ST);
}
case 3: {
PrintQA(QA);
system("pause");
system("cls");
SystemMenu(S,QA,ST);
}
case 4: {
PrintS(S);
system("pause");
system("cls");
SystemMenu(S,QA,ST);
}
case 5: {
exit(0);
}
default :{
printf("您的选择有误,请输入正确的选择!(默认系统退出)");
exit(0);
}
}
}
int main(){
InitStack(S);
InitQueue(QA);
InitStack(ST);
SystemMenu(S,QA,ST);
return 0;
}