目录
一、设计目的
二、问题描述
三、数据结构设计
四、功能(函数设计)
五、图例分析(有图有真相!)
队列——栈类成员
停车场管理类
主函数流程图
六、编码实现
# Queue_Stack.h(头文件,其实是一个类资源文件,根据上机实验修改)
#Queue_Stack.cpp(相应功能的实现)
#Parking_Management.h(类资源文件,包含基本模块、个性化功能)
#Parking_Management.cpp(相应功能的实现)
# main.cpp(测试文件)
七、界面设计
欢迎界面
用户操作界面
进入停车场
离开停车场
查看停车场状况
退出系统
八、运行与测试
理解线性表的逻辑结构和存储结构,进一步提高使用理论知识指导解决实际问题的能力。
设停车场只有一个可停放几辆车的狭长通道,只有一个大门可供汽车出入。汽车在停车场内按车辆到达的先后顺序依次排列,若车场内已经停满了几辆车;则后来的汽车只能在门外的便道上等候,一旦停车场内有车辆开走,则排在便道上的第一辆汽车即刻进入;当停车场内某辆汽车要开走时,由于停车场是狭长的通道,在它之后开入的车辆必须先退出车场为它让路,待车辆开出大门,为它让路的车辆再按原次序进入停车场。试设计这有一个停车场模拟管理系统。
(1)为了便于区分每辆汽车并了解每辆车当前所处的位置,需要记录汽车的车牌号和和汽车的当前状态。
(2)为了便于停车场管理,要为每个车位分配一个固定的编号。
(3)但停车场的停车位都已停满了汽车,又有新的汽车到来时把它调度到便道上,便道上的车辆要按照便道的先后顺序顺次序放在便道上,为便道上的每一个位置分配一个固定的编号。但有车从停车位离开后,便道上的第一辆汽车就立即进入停车场的某个车位。
(4)当某辆车离开停车场时,比它后进停车位的车要给它让路,而且当它开走之后让路的车还要按照原来的停放次序再次进入停车位的某个车位上,为完成这项功能,请定义一个结构体。
本程序从总体上分为4个功能模块,分别为:
(1)程序功能介绍和操作提示模块
(2)汽车进入停车位的管理模块
(3)汽车离开停车位的管理模块
(4)查看停车场状态的查询模块
个性化功能设计():
(1)将停车场状态信息、便道信息写入文件
(2)设计一个计时器管理停车场内每辆车辆的停车时长
该模拟系统的功能实现,我分了五个文件来完成(其实是两个类文件 + 一个测试文件main.cpp),依次为:Queue_Stack.h(头文件)及其相应的Queue_Stack.cpp文件、Parking_Management.h(头文件)及其Parking_Management.cpp文件,最后加一个用于测试的文件,即main.cpp文件。
就是一个队列——栈类文件,包含有基本的与队列、栈有关的函数,还包含了数据成员:停车场栈S1、辅助栈S2、便道汽车组成的队列Q1
// Author: 风吹麦浪~ / leisure-pp //
// History:2023年6月1日 //
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include //输入输出流
#include
#include //文件操作
//#include
#include
using namespace std;
#define stack_init_size 5
typedef string ElemType;//重命名
typedef struct _node //为什么这么用,因为在定义结构体栈时,用c语言的char 、char*
//,跟C++的string.c_str()的相互转化不方便
{
string info = "NULL";
}_node;
typedef struct stack
{
_node* base; //栈空间基址(结点类型)
int capacity; //容量
int top; //栈顶指针
}SeqStack;
typedef SeqStack SeqS; //重命名
typedef string ET; //重命名
typedef struct node //队列结点
{
ET data;
node* next; //指针
}node;
typedef struct linkQueue //队列
{
node* front; //队列头结点
node* rear; //队尾
}linkQueue;
typedef linkQueue LQ; //重命名
///
///
///
class Queue_Stack //创建一个队列和栈的类
{
public:
/// 栈
void Init_Stack(SeqStack* s);
bool EmptyStack(SeqStack* s);
bool Full_Stack(SeqStack* s);
void Push_Stack(SeqStack* s, string x);
void Pop_Stack(SeqStack* s);
string Gethead_Stack(SeqStack* s);
void Show_Stack(SeqStack* s);
int Length_Stack(SeqStack* s);
//void clear(SeqStack* s);
//void destroy(SeqStack* s);
// 队列 //
void Init_Queue(LQ* Q);
void EnQueue(LQ* Q, ET x);
void Pop_Queue(LQ* Q);
void Show_Queue(LQ* Q);
int Length_Queue(LQ* Q);
ET Gethead_Queue(LQ* Q);
bool Empty_Queue(LQ* Q);
~Queue_Stack() {}; //析构函数
public:
SeqS S1; //已停进去的汽车构成的栈
SeqS S2; //当有汽车离开时,再次进入,保证次序的辅助栈
LQ Q1; //在便道上等待的汽车构成的队列
};
// Author: 风吹麦浪~ / leisure-pp //
// History:2023年6月1日 //
#pragma once
#include "Queue_Stack.h"
// 栈 //
//初始化栈
void Queue_Stack::Init_Stack(SeqStack * s)
{
s->base = new _node[stack_init_size]; //开辟stack_init_size个连续的结点空间
s->capacity = stack_init_size; //栈的容量
s->top = 0; //从0开始
}
//判断栈是否为空
bool Queue_Stack::EmptyStack(SeqStack* s)
{
return s->top == 0;
}
//判断栈是否满了
bool Queue_Stack::Full_Stack(SeqStack* s)
{
return s->top >= s->capacity;
}
//入栈
void Queue_Stack::Push_Stack(SeqStack* s, string x)
{
s->base[s->top++].info = x; //从0开始存储数据,记录车牌号信息(控制台输出)
}
//出栈
void Queue_Stack::Pop_Stack(SeqStack* s)
{
if (EmptyStack(s))
return;
s->base[s->top - 1].info = "NULL";
s->top--;
}
//获取栈顶元素
string Queue_Stack::Gethead_Stack(SeqStack* s)
{
if (EmptyStack(s))
{
return "NULL";
}
return s->base[s->top - 1].info;
}
//显示栈的数据信息
void Queue_Stack::Show_Stack(SeqStack* s)
{
for (int i = stack_init_size - 1; i >= 0; --i)
{
string p = s->base[i].info;
cout << "车位" << i + 1 << "对应的车牌号:" << s->base[i].info << endl;
}
cout << endl;
}
//获取栈的长度
int Queue_Stack::Length_Stack(SeqStack* s)
{
return s->top;
}
// 队列 //
//初始化队列
void Queue_Stack::Init_Queue(LQ* Q)
{
Q->rear = Q->front = new node;//开辟一个node类型空间,!!!注意栈中base的结点为 _node
//assert(Q->front != NULL);
Q->front->next = NULL;
}
//入队列
void Queue_Stack::EnQueue(LQ* Q, ET x)
{
node* p = new node;
//assert(p != NULL);
p->data = x;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
}
//出队列
void Queue_Stack::Pop_Queue(LQ* Q)
{
node* p = Q->front;
if (p == Q->rear)
return;
p = p->next;
delete(Q->front);
Q->front = p;
}
//显示队列的基本信息
void Queue_Stack::Show_Queue(LQ* Q)
{
node* p = Q->front->next;
for (int i = 1; i <= stack_init_size; i++)
{
if (p != NULL)
{
cout << "便道" << i << "位置的车牌号:" << p->data << endl;
p = p->next;
}
else
{
cout << "便道" << i << "位置的车牌号:" << "NULL" << endl;
}
}
cout << endl;
}
//获取队列的长度
int Queue_Stack::Length_Queue(LQ* Q)
{
int i = 0;
node* p = Q->front; //若改为 p=Q->front->next ,while(p!=NULL)
while (p != Q->rear) // { i++; p=p->next;} 也行
{
i++;
p = p->next;
}
return i;
}
//获取队列的第一个元素
ET Queue_Stack::Gethead_Queue(LQ* Q)
{
node* p = Q->front;
if (p == Q->rear)
return NULL;
else
{
p = p->next; //头指针不充当存储数据的结点,所以要让p后移
}
return p->data;
}
//判断队列是否为kong
bool Queue_Stack::Empty_Queue(LQ* Q)
{
if (Q->front == Q->rear)
{
return 1;
}
else
{
return 0;
}
}
还是,再一次不厌其烦的介绍下停车场管理类的基本信息吧
包含了成员函数:
Parking_Management()构造函数
void Enter_Parking()进入停车场
void Exit_Parking()离开停车场
void Print()查看停车场的状态
void Save()写入文件
void Get_CurTime()获取每辆车进入停车场的时间
void Out_Time_Price(int tt, string c)缴纳对应停车时长的停车费
包含的数据成员:
int capacity; //停车场最大容量
Postion_information Pos_info[MAX_CAPACITY]; //车位信息
_Path path[MAX_CAPACITY]; //便道信息
const int price=5; //收费标准5元/分钟
Time_node Time[MAX_CAPACITY]; //计时结点
Queue_Stack* QS; //队列——栈类,包含了S1,S2,Q3,及其对应的函数
//
// Author: 风吹麦浪~ / leisure-pp //
// History:2023年6月1日 //
//
#pragma once
#include"Queue_Stack.h"
#include //应用头文件 ,获取系统当前的时间
#define MAX_CAPACITY stack_init_size //最大车位数
typedef struct Postion_information
{
int number; //车位编号
string condition = "未使用"; //车位的状态(正在使用、未使用)
string license_number = "NULL"; //该车位所对应的编号
}Postion_information;
typedef struct _Path
{
int number; //便道编号
string license_number = "NULL"; //该便道所对应的编号
string condition = "未使用"; //便道的状态
}_Path;
//计时操作(结点保存时间)
struct Time_node
{
SYSTEMTIME In; //详细时间 ~年~月~日~分
int begin_time; //入栈时间
int finish_time; //出栈时间
int op_time; //停车时长
};
//
// 停车场管理类 Parking_Management
//
class Parking_Management //Parking_Management管理类
{
public:
Parking_Management(); //初始化停车场基本信息
void Enter_Parking(); //进入停车场(先判断是否满了)
void Exit_Parking(); //离开停车场(需要一个辅助栈来实现)
void Print(); //打印目前停在停车场汽车对应的编号
//个性化
void Save();//文件保存停车场、便道信息
void Get_CurTime();//每辆车的获取入栈时间
void Out_Time_Price(int tt, string c); // 输出要缴纳的停车费
virtual ~Parking_Management() {}
private:
int capacity; //最大容量
const int price = 5; // 5元/分钟
Postion_information Pos_info[MAX_CAPACITY]; //车位信息
_Path path[MAX_CAPACITY]; //便道信息
Queue_Stack* QS;//队列—栈类,包含了S1,S2,Q3,及其对应的函数
Time_node Time[MAX_CAPACITY]; //计时结点
};
// Author: 风吹麦浪~ / leisure-pp //
// History:2023年6月1日 //
#include "Parking_Management.h"
//基本功能
Parking_Management::Parking_Management() //构造函数
{
capacity = MAX_CAPACITY; //容量,即停车场的车位数
QS = new Queue_Stack; //申请一个类的空间
QS->Init_Stack(&QS->S1); //初始化栈S1
QS->Init_Stack(&QS->S2); //初始化栈辅助栈S2
QS->Init_Queue(&QS->Q1); //初始化队列Q3
for (int i = 0; i < MAX_CAPACITY; i++)
{
Pos_info[i].number = i + 1; //初始化编号
path[i].number = i + 1;
}
}
void Parking_Management::Enter_Parking()
{
system("cls");
string flag = "1"; //判断该入栈操作是否继续或者是结束
do
{
string license_n; //车牌号
cout << "请输入您的车牌号:";
cin >> license_n;
if (QS->Full_Stack(&QS->S1)) //如果栈已满,则进入便道
{
if (QS->Length_Queue(&QS->Q1) != MAX_CAPACITY)
{
QS->EnQueue(&QS->Q1, license_n);//进入便道
int t = QS->Length_Queue(&QS->Q1);//每次都获取队列长度
path[t - 1].license_number = license_n; //更新便道状态
path[t - 1].condition = "正在占用";
cout << "\n停车位已满,正在进入便道.....\n";
}
else
{
cout << "\n便道也满了,请先执行[3]操作" << endl;
Sleep(1300);
return;
}
}//end of if
else
{
QS->Push_Stack(&QS->S1, license_n); //入栈,也即进入停车场
int t = QS->Length_Stack(&QS->S1); //获取当前栈的长度
Pos_info[t - 1].license_number = license_n;//记录车牌号
Pos_info[t - 1].condition = "正在使用"; //更新停车位状态
Get_CurTime(); //记录进入停车场的时间
}
do //做异常输入处理
{
cout << " 是否继续(0结束、1继续):";
cin >> flag;
} while (flag != "0" && flag != "1");
} while (flag == "1");
}
void Parking_Management::Exit_Parking()
{
int sign = 0, flag = 0;
int tt; //保存修改信息的停车位的下标位置
Print();
string ss1, p;
if (!QS->EmptyStack(&QS->S1))
{
cout << "\n请输入停车场要离开的车牌号:";
cin >> ss1;
}
else
{
cout << "\n停车场为空,请先执行[2]操作...\n\n";
system("pause");
return;
}
//int S_len = QS->Length_Stack(&QS->S1);
while (!QS->EmptyStack(&QS->S1))
{
p = QS->Gethead_Stack(&QS->S1); //获取栈顶元素
if (p == ss1) //找到了该车的位置
{
//判断便道上是否有车辆
if (!QS->Empty_Queue(&QS->Q1))
{
sign = 1;
for (int i = 0; i < MAX_CAPACITY; i++)
{
if (p == Pos_info[i].license_number) //找到相应车位对应的车牌号
{
cout << endl;
int j = i + 1;
for (; j < MAX_CAPACITY && Pos_info[j].license_number != "NULL"; j++)
{
cout << "车牌号:" << Pos_info[j].license_number << "已让位" << endl;
}
cout << endl;
p = QS->Gethead_Queue(&QS->Q1);
Pos_info[i].license_number = p; //更新车位信息
QS->Pop_Queue(&QS->Q1); //删除队列的第一个元素
tt = i;
for (int i = 0; i < MAX_CAPACITY - 1; i++) // 更新便道信息
{
path[i].condition = path[i + 1].condition; //前移一位
path[i].license_number = path[i + 1].license_number;
}
path[MAX_CAPACITY - 1].license_number = "NULL";
path[MAX_CAPACITY - 1].condition = "未使用";
cout << " 请按任意键查看该车的交费信息...";
getchar();
getchar();
system("cls");
Out_Time_Price(tt, ss1);
break;
}
}
}
//便道没车
else
{
if (flag == 0)
{
flag = 1;
int i;
for (i = 0; i < MAX_CAPACITY; i++) {
if (ss1 == Pos_info[i].license_number) {
tt = i;
cout << endl;
for (i = i + 1; i < MAX_CAPACITY && Pos_info[i].license_number != "NULL"; i++)
{
cout << "车牌号:" << Pos_info[i].license_number << "已让位" << endl;
}
cout << endl;
break;
}
}
cout << " 请按任意键查看该车的交费信息...";
getchar();
getchar();
system("cls");
Out_Time_Price(tt, ss1);
for (i = tt; i < MAX_CAPACITY - 1; i++)
{
//信息前移的同时,时间也要跟着移动
Time[i].In = Time[i + 1].In;
Time[i].begin_time = Time[i + 1].begin_time;
Pos_info[i].license_number = Pos_info[i + 1].license_number;
Pos_info[i].condition = Pos_info[i + 1].condition;
}
Pos_info[i].license_number = "NULL";
Pos_info[i].condition = "未使用";
}
}
}
if (p != ss1)
{
string h = p;
QS->Push_Stack(&QS->S2, h); //用辅助栈储存信息
}
QS->Pop_Stack(&QS->S1); //删除栈顶元素
}
//重新计时
if (sign == 1)
{
SYSTEMTIME t;
GetLocalTime(&t);
Time[tt].In = t;
Time[tt].begin_time = t.wMinute;
Time[tt].op_time = 0;
}
while (!QS->EmptyStack(&QS->S2)) //重新将辅助栈的信息导入停车场栈结构
{
string p = QS->Gethead_Stack(&QS->S2);
QS->Push_Stack(&QS->S1, p);
QS->Pop_Stack(&QS->S2);
}
system("cls");
}
void Parking_Management::Print()
{
system("cls");
cout << "\n停车场基本信息:共" << MAX_CAPACITY << "个车位" << endl << endl;
if (QS->EmptyStack(&QS->S1))
{
cout << "当前停车场为空...\n\n" << endl;
return;
}
QS->Show_Stack(&QS->S1);
cout << " \n便道基本信息: (队列)\n\n";
QS->Show_Queue(&QS->Q1);
}
//个性化
void Parking_Management::Save()
{
ofstream outfile("停车场管理系统.txt", ios::trunc);
if (!outfile)
{
cerr << "未打开文件\n";
return;
}
outfile << "\t停车场模拟管理系统\n" << endl;
outfile << "\t停车场基本信息:" << endl;
for (int i = MAX_CAPACITY; i >= 1; i--)
{
outfile << "车位" << i << "的状态:" << Pos_info[i - 1].condition << " ";
outfile << "车牌号:" << Pos_info[i - 1].license_number << endl;
}
outfile << endl << "\t便道基本信息:" << endl;
for (int i = 1; i <= MAX_CAPACITY; i++)
{
outfile << "便道" << i << "的状态:" << path[i - 1].condition << " ";
outfile << "车牌号:" << path[i - 1].license_number << endl;
}
outfile.close();
}
void Parking_Management::Get_CurTime()
{
SYSTEMTIME cur_time;
GetLocalTime(&cur_time); //获取当前的详细时间
int p = QS->Length_Stack(&QS->S1) - 1;
Time[p].In = cur_time; //当前入栈的详细时间
Time[p].begin_time = (int)cur_time.wMinute; //我们只记录分钟
}
void Parking_Management::Out_Time_Price(int tt, string c)
{
SYSTEMTIME out_time;
GetLocalTime(&out_time); //出栈时间
int p = tt; ///找到对应位置(为了获取)费用信息
Time[p].finish_time = out_time.wMinute;
if (Time[p].begin_time < Time[p].finish_time) //未进位,即hour (时钟)相同
{
Time[p].op_time = Time[p].finish_time - Time[p].begin_time;
}
else if (Time[p].begin_time > Time[p].finish_time) //让 finish_time += 60
{
Time[p].finish_time += 60;
Time[p].op_time = Time[p].finish_time - Time[p].begin_time;
}
else if (Time[p].begin_time == Time[p].finish_time)
{
Time[p].op_time = 1; //不足一分钟按一分钟计算,有疑问看结构体定义
}
cout << " 车牌号为:" << c << endl << endl;
cout << "进入时间:";
cout << Time[p].In.wYear << "年" << Time[p].In.wMonth << "月" << Time[p].In.wDay
<< "日" << Time[p].In.wHour << "点" << Time[p].In.wMinute << "分" << endl;
cout << "离开时间:";
cout << out_time.wYear << "年" << out_time.wMonth << "月" << out_time.wDay
<< "日" << out_time.wHour << "点" << out_time.wMinute << "分" << endl;
cout << "停车时长为:" << Time[p].op_time << "分钟" << endl;
cout << "应缴费用为:" << Time[p].op_time * price << "元" << endl << endl;
system("pause");
}
//线性结构
//基础数据结构解决实际问题
//栈
//队列
//等候
//出栈麻烦
//状态
//车牌号
//车位编号
//便道编号
//两种思路
//顺序、替换
//个性化
//
//
//
#include
#include"Queue_Stack.h"
#include"Parking_Management.h"
//开始
void Start()
{
SYSTEMTIME time;
GetLocalTime(&time);
cout<<" 欢迎使用停车场模拟管理系统!\n\n";
cout << "当前时间:";
cout << time.wYear << "年" << time.wMonth << "月" << time.wDay
<< "日" << time.wHour << "点" <
(1)连续有7辆汽车到来,牌照号分别为CF001、CF002、CF003、CF004、CF005、CF006、CF007,前5辆车应该进入停车位1-5车位,第6、7辆车应停入便道的1、2位置上。
(2)上面(1)中的情况发生后,让牌照CF003的汽车从停车场开走,应显示CF005、CF004的让路动作和CF006从便道到停车位的动作。
(3)随时检查停车位和便道的状态,不应该出现有空位而便道上还有车的情况。
(4)其它正常操作的一般情况。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/icc_hhy/article/details/130966880