最近花时间写了一个停车场管理系统。算是比较完善的一个小系统,在这里分享一下该系统的一些设计。
一、停车场管理
设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。
试为停车场编制按上述要求进行管理的模拟程序。
(1)汽车可有不同种类,则它们的占地面积不同,收费标准也不同,如1辆客车和1.5辆小汽车的占地面积相同,1辆十轮卡车占地面积相当于3辆小汽车的占地面积。如何处理该问题?
解决方案:为了简化问题,根据车型(本题中有三种:小汽车,大卡车,十轮客车)的不同,收费标准直接和占地面积成正比例。
(2)汽车可以直接从便道上开走,此时排在它前面的汽车要先开走让路,然后再依次排到队尾。如何处理该问题?
解决方案:汽车从便道开到停车场时,可使用队列的数据结构(先进先出,且只能在队尾增加元素,队头不能增加元素);当汽车直接从便道开走时,排在他前面的汽车要开走在排到队尾,可见,先开入便道的车辆 ,即队头,先离开便道,然后到队尾入队。因此,在允许汽车可以直接从便道开走时,应该使用队列来存储便道上的汽车。
二、算法设计
1、利用栈和队列模拟车辆进出;
2、充分考虑停车时间的复杂计算,包括平年和闰年,大月和小月以及任意日期之间的小时数计算;
3、运用顺序查找和折半查找对比查询功能的时间复杂度;
三、数据结构选择
对象car:
自定义一个Car的类,包含汽车的车牌号,车的颜色,车型,停车时间。
class Car{
public:
string licensePlate;//车牌号
string color;//车的颜色
string model;//车型
string time;//停车时间
};
停车场
根据汽车在停车场的特点(后进先出),存储停车场内的各种汽车选择栈stack来存储。考虑到栈无法遍历(遍历时无法存储已有的数据)的特点,同时定义一个Car类型的数组a[100]来存储停车场内的车辆信息,里面的数据和stack的数据是同步的。
Car a[100];//防止遍历清空数据,与Parking同步
stack<Car> Parking;//停车场,有初始值
便道
根据汽车在便道的进出特点(先进入便道的车先进入停车场),选择队列queue来存储在便道上的车辆信息。
queue<Car> Waiting;//便道等待停车的车辆在排队,有初始值
停车时间
考虑到要从文件中读取车辆信息,读取的信息是string类型,但时间计算是数值型,为了方便通过时间计算停车费用,没有单独对年月日进行定义,而是将时间格式(形如2019-7-30,12:30)统一,定义为string类型。读取信息后对字符串进行分割处理,得到汽车停车时间(年、月、日、时、分)。
四、功能设计
class Manage{
public:
void add();//停车
void inquire();//查询
void show();//显示函数
void modification();//信息修改函数
void del();//出停车场
void statistics();//统计车辆信息函数
void save();//写入文件函数
void loadsave();//修改信息后重新写入文件函数
void load();//运行程序后加载最新数据函数
};
具体函数实现可下载我上传的资源进行查看,里面包含输入输出的TXT文件以及各个文件的作用说明。
资源链接:https://download.csdn.net/download/chengxuyuanliwanwan/11461187
五、特色
出停车场时,时间格式的转化、时间的准确计算以及折半查找的应用都在一定程度上优化了代码。
出停车场模拟
void Manage::del() {
int j;
string c;
cout<<"欢迎出停车场!"<<endl;
cout<<"请输入您想出停车场车辆的车牌号码:"<<endl;
cin>>c;
for(j=0;j<i;j++){//从数组a里删除
if(c.compare(a[j].licensePlate)==0){
cout<<"您的停车时间为"<<a[j].time<<endl;
cout<<"请输入您离开停车场的时间:"<<endl;
string endtime;
cin>>endtime;
//计算缴纳的费用
int data1[3],data2[3],time1[2],time2[2];
char *s1=(char*)a[j].time.data();//停车时间
char *t1[5];
int count1=0;
while((t1[count1]=strtok(s1,"-,:"))!=NULL){
count1++;
s1=NULL;
}
//构造停车时间的参数
data1[0]=atoi(t1[0]);
data1[1]=atoi(t1[1]);
data1[2]=atoi(t1[2]);
time1[0]=atoi(t1[3]);
time1[1]=atoi(t1[4]);
char *s2=(char*)endtime.data();//离开停车场的时间
char *t2[5];
int count2=0;
while((t2[count2]=strtok(s2,"-,:"))!=NULL){
count2++;
s2=NULL;
}
//构造离开停车场的时间的参数
data2[0]=atoi(t2[0]);
data2[1]=atoi(t2[1]);
data2[2]=atoi(t2[2]);
time2[0]=atoi(t2[3]);
time2[1]=atoi(t2[4]);
double mtime;
mtime = HoursCount(data1,time1,data2,time2);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
cout<<"您的车在停车场停留了 "<<mtime<<" hours"<<endl;
string ccar="小汽车";
string PassengerCar="大卡车";
string Truck="十轮客车";
double perprice;
if(ccar.compare(a[j].model)==0){perprice=1;}
if(PassengerCar.compare(a[j].model)==0){perprice=1*1.5;}
if(Truck.compare(a[j].model)==0){perprice=1*10;}
double cost=mtime*perprice;
cout<<"请缴纳"<<fixed<<setprecision(2)<<cost<<"元的停车费"<<endl;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);
for(int k=j;k<i-1;k++){
a[k].licensePlate=a[k+1].licensePlate;
a[k].color=a[k+1].color;
a[k].model=a[k+1].model;
a[k].time=a[k+1].time;
}
break;
}
}
i--;
//从Parking里删除
//让路的车写入back.txt里
ofstream backFile("back.txt");//加到文本文件里
ofstream newFile("new.txt");//加到文本文件new.txt里
for(j=0;j<Parking.size();j++){
if(c.compare(Parking.top().licensePlate)!=0){
Backing.push(Parking.top());//让路
backFile<<Parking.top().licensePlate<<"\t"<<Parking.top().color<<"\t"<<Parking.top().model<<"\t"<<Parking.top().time<<endl;
Parking.pop();//弹出
}
else{
Parking.pop();//弹出
//退出让路的车辆的重新开到停车场回来
while(!Backing.empty()){
Parking.push(Backing.top());//将栈顶元素放入停车场
Backing.pop(); //弹出栈顶元素
}
int s=Parking.size(),g=0;
while(g<s) {
newFile<<Parking.top().licensePlate<<"\t"<<Parking.top().color<<"\t"<<Parking.top().model<<"\t"<<Parking.top().time<<endl;
if(Parking.empty()) {
break;
}
Parking.pop();
g++;
}
break;
}
}
backFile.close();
newFile.close();
}
折半查找实现查询功能
int BinSearch(Car a[],string k){
int n=i;
int low=0,high=n-1,mid;
int data1[3],data2[3],time1[2],time2[2];
char *s1;
char *t1[5];
int l=0,atime[i][5];
while(l<n){
s1=(char*)a[l].time.data();//停车时间
int count1=0;
while((t1[count1]=strtok(s1,"-,:"))!=NULL){
count1++;
s1=NULL;
}
//构造停车时间的参数
atime[l][0]=atoi(t1[0]);
atime[l][1]=atoi(t1[1]);
atime[l][2]=atoi(t1[2]);
atime[l][3]=atoi(t1[3]);
atime[l][4]=atoi(t1[4]);
l++;
}
char *s2=(char*)k.data();//离开停车场的时间
char *t2[5];
int count2=0;
while((t2[count2]=strtok(s2,"-,:"))!=NULL){
count2++;
s2=NULL;
}
//构造离开停车场的时间的参数
data2[0]=atoi(t2[0]);
data2[1]=atoi(t2[1]);
data2[2]=atoi(t2[2]);
time2[0]=atoi(t2[3]);
time2[1]=atoi(t2[4]);
start=clock();
while(low<=high){
mid=(low+high)/2;
if(data2[0]<atime[mid][0])
{ high=mid-1;}
else if(data2[0]>atime[mid][0])
{ low=mid+1;}
else {
if(data2[1]<atime[mid][1])
{ high=mid-1; }
else if(data2[1]>atime[mid][1])
{ low=mid+1; }
else
{
if(data2[2]<atime[mid][2])
{ high=mid-1; }
else if(data2[2]>atime[mid][2])
{ low=mid+1; }
else
{
if(time2[0]<atime[mid][3])
{ high=mid-1; }
else if(time2[0]>atime[mid][3])
{ low=mid+1; }
else
{
if(time2[1]<atime[mid][4])
{ high=mid-1; }
else if(time2[1]>atime[mid][4])
{ low=mid+1; }
else
{
end=clock();
x=end-start;
return mid;
}
}
}
}
}
}
return -1;
}
本次设计过程中学会了很多东西,很多库函数的应用大大简化了代码,自己还需努力!