# 停车场管理系统设计报告
# 1 需求分析
## 1.1问题描述
停车场内只有一个可停放 *n* 辆汽车的狭长通道,且只有一个大门可供汽车进出。
汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在停车场的最北端),若车场内已停满 *n* 辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入。
当停车场内某辆车要离开时,在它之后开入的车辆必须先退出车场为它让路,待该辆车开出大门外,其它车辆再按原次序进入车场,每辆停放在车场的车在它离开车场时必须按它停留的时间长短交纳费用。
试为停车场编制按上述要求进行管理的模拟程序。
## 1.2基本要求
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理;
每一组输入数据包括三个数据项:汽车“到达”或“离去”信息、汽车牌照号码及到达或离去的时刻,对每一组输入数据进行操作后的输出数据为:若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费);
栈以顺序结构实现,队列以链表实现。
# 2 概要设计
## 2.1数据结构
### 2.1.1时间类
时间是进行收费的依据,此处假定时间在一天之内。时间类既可以表示一个时刻,也可以表示一段时间长度。
时间类数据成员:
- hour:指示时钟
- minute:指示分钟
时间类成员函数:
- Time:构造函数
- operator+=:进行时间的复合加法,即将相加后的结果赋给当前对象,并返回当前对象
- operator-=:进行时间的复合减法,即将相减后的结果赋给当前对象,并返回当前对象
|**Time**|
| :-: |
|<p>+ hour: int</p><p>+ minute: int</p>|
|<p>+ Time()</p><p>+ Time(hour: int, minute: int)</p><p><<friend>> operator+(left: const Time&, right: const Time&): Time</p><p>+ operator+=(right: const Time&): Time</p><p><<friend>> operator-(left: const Time&, right: const Time&): Time</p><p>+ operator-=(right: const Time&): Time</p><p><<friend>> operator==(left: const Time&, right: const Time&): bool</p><p><<friend>> operator<(left: const Time&, right: const Time&): bool</p><p><<friend>> operator<=(left: const Time&, right: const Time&): bool</p><p><<friend>> operator>(left: const Time&, right: const Time&): bool</p><p><<friend>> operator>=(left: const Time&, right: const Time&): bool</p><p><<friend>> operator<<(os: ostream&, t: const Time&): ostream&</p>|
时间类非成员函数:
- operator+:时间加法
- operator-:时间减法
- operator==:判断时间是否相等
- operator<:判断前一个时间是否小于后一个时间
- operator<=:判断前一个时间是否小于等于后一个时间
- operator>:判断前一个时间是否大于后一个时间
- operator>=:判断前一个时间是否大于等于后一个时间
- operator<<:将时间输出到输出流中
### 2.1.2汽车类
汽车是后续操作的基础元素,结合题目要求,汽车应包含牌照号码、停车时间等数据。汽车类数据成员:
- number:汽车牌照号码
- lastTime:最后一次在停车场(栈)内的时刻
- parking: 停车时间
lastTime 和 parking 并非实时更新,而是当有车辆到达或离去时才会做相应的改变。
|**Car**|
| :-: |
|<p>- number: string</p><p>- lastTime: Time</p><p>- parking: Time</p>|
|<p>+ Car()</p><p>+ Car(number: string)</p><p>+ operation==(car: const Car&): bool</p><p>+ updateLastTime(time: const Time&)</p><p>+ setLastTime(time: const Time&)</p><p>+ getLastTime(): Time</p><p>+ addParkingTime(time: const Time&)</p><p><<friend>> operator<<(os: ostream&, t: const Car&): ostream&</p>|
汽车类成员函数:
- Car:构造函数
- operation==:判断是否为同一辆汽车(只判断牌照号码)
- updateLastTime:设置最后一次在停车场(栈)内的时刻,并增加停车时间
- setLastTime:设置最后一次在停车场(栈)内的时刻
- getLastTime:获取最后一次在停车场(栈)内的时刻
- addParkingTime:增加停车时间
- getParingTime:获取停车时间
汽车类非成员函数:
- operator<<:将汽车信息输出到输出流中
### 2.1.3栈类模板
栈是一种“先进后出”的数据结构,此处用于组织停车场内汽车的停放。我们选用线性结构实现栈,并进行模板化,以便下次复用。
模板参数 T1,表示基础元素类型,在编写代码时,可设为 Car。
从模板参数 T,定义出以下几种嵌套类型:
0. *T −→ value*\_*type*,基础元素类型
0. *T∗ −→ pointer*,指针
0. *const T∗ −→ const*\_*pointer*,常指针
0. *T* & *−→ reference*,引用
0. *const T* & *−→ const*\_*reference*,常引用
|**Stack<T>**|
| :-: |
|<p>- \_top: pointer</p><p>- \_base: pointer</p><p>- \_cap: pointer</p>|
|<p>+ Stack()</p><p>*∼* Stack()</p><p>+ operator[](pos: size\_type): reference</p><p>+ operator[](pos: size\_type): const\_reference</p><p>+ top(): reference</p><p>+ top(): const\_reference</p><p>+ empty(): bool</p><p>+ size(): size\_type</p><p>+ capacity(): size\_type</p><p>+ push(data: const\_reference)</p><p>+ pop()</p><p>+ index(data: const\_reference): size\_type</p><p>+ print()</p><p>+ reserve(newCapacity: size\_type)</p>|
栈类数据成员:
- \_top 栈顶
- \_base 栈底
- \_cap 当前栈存储空间的尾部
特别指出,栈顶指针 \_top,其初值指向栈底,即 \_top == \_base 可作为栈空的标记,每当插入新的栈顶元素时,指针 \_top 增 1;删除栈顶元素时,指针 \_top 减 1,因此,非空栈中的栈顶指针始终在栈顶元素的下一个位置上。
\_cap 指针则仅指示当前栈存储空间的尾部,其真实地址则是尾部的下一个位置。这两种设计都是为了方便程序的编写。
栈类成员函数:
- Stack:构造函数
- *∼*Stack:析构函数
- operator[]:访问器
- top:访问栈顶
size\_type 是无符号超长整型,源于 std::size\_t。
设置访问器仅用于方便本次项目的代码编写,破坏了栈的设计原则,在编写一般程序时,不应在栈中设置访问器。
- empty:判断栈是否为空
- size:获取栈长
- capacity:获取栈的存储容量
- push:入栈
- pop:出栈
- index:寻找元素的第一个位置
- print:打印栈
- reserve:重新分配存储空间容量
### 2.1.4队列类模板
队列,是一种“先进先出”的数据结构,此处可用于模拟停车场外的便道。我们选用链式结构实现队列,并进行模板化,以便下次复用。
模板参数 T1,表示基础元素类型,在编写代码时,可设为 Car。
首先设计一个队列节点类,与链表节点类似:
|**QNode<T>**|
| :-: |
|<p>- \_data: value\_type</p><p>- \_next: node\_ptr</p>|
|<p>+ QNode()</p><p>+ QNode(data: const\_reference, next = nullptr: const\_node\_ptr)</p><p>+ data(): reference</p><p>+ data(): const\_reference</p><p>+ setData(data: const\_reference)</p><p>+ next(): node\_ptr</p><p>+ next(): const\_node\_ptr</p><p>+ setNext(next: const\_node\_ptr)</p>|
队列节点类数据成员:
_data:数据域
从模板参数 T 定义出的嵌套类型与 Stack 类相似,但增加了 4 个嵌套定义:
- QNode < T > ∗ −→ node*\_*ptr*,节点指针
- const QNode < T > ∗ −→ const*\_*node*\_*ptr*,节点常指针
- *QNode < T >* & *−→ node*\_*ref* ,节点引用
- const QNode < T >* & *−→ c