#include<iostream>
#include<fstream>
using namespace std;
#define MAX_SIZE 2//停車場能夠容納的車的數量
#define FARE 5//表示停車場的收費為每小時FARE元
int CountForStack=0;// 此全域變數用來計數堆棧現有的車數
int CountForQueue=0;// 此全域變數用來計數隊列現有的車數
typedef struct//這個節點用來儲存每輛車的資訊
{
char Condition ;//用來表示“到達”或者“離開”的狀態," "表示還沒有到達,也沒有離開
int ArriveTime;//用來記錄到達時間,預設為-1,說明還沒有到達
int LeaveTime;// 用來記錄離開時間,預設為-1,說明還沒有離開
int License;// 記錄車牌號
}CarNode;
typedef struct //棧的定義
{
CarNode *base;//棧底指標,指向0
CarNode *top;//棧頂指標,如果指向0,說明棧為空白
int stacksize;//棧的容量大小
}CarStack;
typedef struct QNode//隊列節點的定義
{
char Condition ;//用來表示“到達”或者“離開”的狀態," "表示還沒有到達,也沒有離開
int ArriveTime;//用來記錄到達時間,預設為-1,說明還沒有到達
int LeaveTime;// 用來記錄離開時間,預設為-1,說明還沒有離開
int License;// 記錄車牌號
QNode *next;//指向下一個節點的指標
}QNode;
typedef struct// 隊列的定義
{
QNode *front;//隊頭指標
QNode *rear;//隊尾指標
}Queue;
bool InitStack(CarStack &S)//此函數用來初始化棧
{
S.base =(CarNode *)malloc(MAX_SIZE*sizeof(CarNode));
if(!S.base )
{
cout<<"記憶體配置失敗!"<<endl;
return false;//說明記憶體配置失敗,返回false
}
S.top =S.base ;
S.stacksize =MAX_SIZE;
return true;
}
bool InitQueue(Queue &Q)//此函數用來初始化隊列
{
Q.front =(QNode *)malloc(sizeof(QNode));
if(!Q.front )
{
cout<<"記憶體配置失敗!"<<endl;
return false;
}
Q.rear =Q.front ;
Q.front ->next =0;//下一個節點指空
return true;
}
bool EnQueue(Queue &Q,QNode &qnode)//此函數用來入隊一個節點
{
QNode *p=(QNode *)malloc(sizeof(QNode));
if(!p)
{
cout<<"記憶體配置失敗!"<<endl;
return false;
}
p->ArriveTime =qnode.ArriveTime ;
p->Condition =qnode.Condition ;
p->LeaveTime =qnode.LeaveTime ;
p->License =qnode.License ;
p->next =0;
Q.rear ->next =p;
Q.rear =p;
return true;
}
bool DeQueue(Queue &Q,QNode &t)//此函數用來出隊
{
if(Q.front ==Q.rear )
{
cout<<"隊列為空白!"<<endl;
return false;
}
QNode *p=Q.front->next ;
t.ArriveTime =p->ArriveTime ;
t.Condition =p->Condition ;
t.LeaveTime =p->LeaveTime ;
t.License =p->License ;
Q.front ->next =p->next ;
if(Q.rear ==p)//如果P是指向最後一個出隊的元素
Q.rear =Q.front ;
free(p);
return true;
}
void InitCarNode(CarNode &C,char condition,int arrivetime,int leavetime,int license)//本函數用來初始化一個CarNode 節點
{
C.ArriveTime =arrivetime;
C.Condition =condition;
C.LeaveTime =leavetime;
C.License=license;
}
bool Push(CarStack &S,CarNode &car)//此函數用來入棧一個CarNode 節點
{
if(S.top -S.base >=S.stacksize )
{
cout<<"此棧已滿,不能壓入新的資訊"<<endl;
return false;
}
(*S.top ).ArriveTime =car.ArriveTime ;
(*S.top ).Condition =car.Condition ;
(*S.top ).LeaveTime =car.LeaveTime ;
(*S.top ).License =car.License ;
++S.top ;//棧頂指標上移
return true;
}
bool Pop(CarStack &S,CarNode &t)//此函數用來彈出棧內元素
{
if(S.top ==S.base )
{
cout<<"棧空,不能執行出棧操作!"<<endl;
return false;
}
--S.top ;//棧頂指標下移
t.ArriveTime =(*S.top ).ArriveTime ;
t.Condition =(*S.top ).Condition ;
t.LeaveTime =(*S.top ).LeaveTime ;
t.License =(*S.top ).License ;
return true;
}
bool IsStackFull(CarStack &S)//此函數用來判斷堆棧是否已滿
{
if(S.top -S.base >=S.stacksize )
return true;
else
return false;
}
bool IsStackEmputy(CarStack &S)//此函數用來判斷堆棧是否為空白
{
if(S.top ==S.base )
return true;
else
return false;
}
bool IsQueueEmputy(Queue &Q)//此函數用來判斷隊列是否為空白
{
if(Q.front ==Q.rear )
return true;
else
return false;
}
bool SearchInStack(CarStack&S,int a)//a表示要尋找的車牌號,如果在停車場裡面,就返回true
{
bool tag=false;
if(!IsStackEmputy(S))
{
CarNode *p=S.top-1 ;
while(p!=S.base )
{
if((*p).License ==a)
tag=true;
--p;
}
if((*p).License ==a)
tag=true;
}
return tag;
}
bool SearchInQueue(Queue &Q,int a)//a表示要尋找的車牌號,如果在通道裡面,就返回true
{
bool tag=false;
if(!IsQueueEmputy(Q))//如果隊列非空
{
QNode *p=Q.front->next ;
while(p!=Q.rear)
{
if((*p).License ==a)
tag=true;
}//退出此while迴圈時p指向最後一個元素
if((*p).License ==a)
tag=true;
}
return tag;
}
void InCar(CarStack &S,Queue &Q,int a1,int a2)//此函數用來表示進入車輛, 參數a1用來表示到達時間,參數a2表示車牌號碼
{
if(SearchInStack(S,a2))
{
cout<<"車號"<<a2<<"已經存在於停車場內,輸入有誤"<<endl;
return ;
}
if(SearchInQueue(Q,a2))
{
cout<<"車號"<<a2<<"已經存在於通道內,輸入有誤"<<endl;
return ;
}
if(IsStackFull(S))//如果堆棧已滿,說明停車場已滿,需要停車在通道
{
QNode qnode;
qnode.ArriveTime =-1;//在通道時間不收費,所以不計時
qnode.Condition ='A';
qnode.LeaveTime =-1;//定義為-1,說明還沒有開始離開
qnode.License =a2;
EnQueue(Q,qnode);//停在通道上
++CountForQueue;
cout<<"車號:"<<qnode.License <<"停在通道的第"<<CountForQueue<<"號位置"<<endl;
}
else
{
CarNode carnode;
carnode.ArriveTime =a1;
carnode.Condition ='A';
carnode.LeaveTime =-1;
carnode.License =a2;
Push(S,carnode);
++CountForStack;
cout<<"車號:"<<carnode.License <<"到達時間 "<<carnode.ArriveTime <<"停在停車場的第"<<CountForStack<<"號位置"<<endl;
}
}
void OutCar(CarStack &S,Queue &Q,int a1,int a2)//此函數用來出車,參數a1用來表示離開時間,參數a2表示車牌號碼
{
if(SearchInQueue(Q,a2))
{
cout<<"車號"<<a2<<"存在於通道內,還未進入停車場,不能離開"<<endl;
return ;
}
if(!SearchInStack(S,a2))
{
cout<<"車號"<<a2<<"不在停車場內,輸入有誤"<<endl;
return ;
}
CarStack tempstack;
InitStack(tempstack);//建立並且初始化用於暫存出車時讓車的堆棧
bool tag1=false;//標誌這個停車場出車以前是否已滿,預設為沒有滿
tag1=IsStackFull(S);
bool tag2=true;//標誌通道是否有汽車在等待, 預設為通道為空白
tag2=IsQueueEmputy(Q);
CarNode temp;//用來儲存暫時取出的汽車
bool tag3=false;//用來標誌是否是離開時間小於到達時間而導致離開失敗,true表示離開失敗
while(1)//讓車離開
{
Pop(S,temp);
if(temp.License ==a2)
{
if(a1<temp.ArriveTime )
{
cout<<"輸入有誤,離開時間不能小於到達時間,離開失敗"<<endl;
tag3=true;
Push(tempstack,temp);
}
else
cout<<"車號"<<a2<<"現在離開停車場,所用的時間為"<<a1-temp.ArriveTime <<"收費為"<<(a1-temp.ArriveTime )*FARE<<endl;
break;
}
else
Push(tempstack ,temp);//進入暫存棧
}
while(!IsStackEmputy(tempstack))//倒出的車再次進入停車場
{
Pop(tempstack,temp);
Push(S,temp);
}
QNode tempqnode;//用來暫時儲存從通道出來的汽車
if(tag1==true&&tag2==false&&tag3==false)//如果出車前停車場已滿,並且通道不為空白,並且離開沒有失敗
{
DeQueue(Q,tempqnode);
--CountForQueue;
temp.ArriveTime =a1 ;
temp.Condition =tempqnode.Condition ;
temp.LeaveTime =tempqnode.LeaveTime ;
temp.License =tempqnode.License ;
Push(S,temp);
}
if(tag2==true&&tag3==false)// 如果停車場沒有滿,並且離開成功
--CountForStack;
}
void showmenu(CarStack &S,Queue &Q)
{
cout<<"******************************選擇菜單*******************************"<<endl;
cout<<" 1: 停車"<<endl;
cout<<" 2: 離開"<<endl;
cout<<" 3: 退出"<<endl;
cout<<"*****************************請按鍵選擇******************************"<<endl;
int tag;
cin>>tag;
while(tag!=1&&tag!=2&&tag!=3)
cin>>tag;
int a1;
unsigned int a2;
switch(tag)
{
case 1:
cout<<"請輸入到達的車號"<<endl;
cin>>a1;
cout<<"請輸入到達時間"<<endl;
cin>>a2;
InCar(S,Q,a2,a1);
break;
case 2:
cout<<"請輸入離開的車號"<<endl;
cin>>a1;
cout<<"請輸入離開的時間"<<endl;
cin>>a2;
OutCar(S,Q,a2,a1);
break;
case 3:
return ;
break;
}
char ch;
cout<<"*******************按E/e退出,按任意鍵返回菜單**************************"<<endl;
cin>>ch;
if(ch!='E'&&ch!='e')
showmenu(S,Q);
}
void main()
{
CarStack carstack;
InitStack(carstack);// 建立並且初始化用於停車場的堆棧
Queue carqueue;
InitQueue(carqueue);//建立並且初始化用於通道的隊列
showmenu(carstack,carqueue);
}