综合性实验:停车场管理程序

/**
*    实验题目:
*        停车场管理程序
*    实验目的:
*        深入掌握栈和队列应用的算法设计
*    实验内容:
*        设停车场内只有一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。
*    汽车在停车场内按车辆到达时间的先后顺序,依次由南向北排列(大门在最北端,最
*    先到达的第一辆车停放在车场的最南端),若车场内已停满n辆车,则后来的汽车只能
*    在门外的便道即候车场上等候,一旦有车开走,则排在便道上的第一辆车即可开入;
*    当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车
*    开出大门外,其他车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时
*    必须按它停留的时间长短交纳费用。
*    用栈模拟停车场,用队列模拟车场外的便道,按照从键盘获候车场中的车辆:104取的数据序列进行模拟管理。
*    每一组输入数据包括3个数据项:汽车到达(1)或者离开(2)、汽车牌照号码以及到达或者
*    离开的时刻。对每一组输入数据进行操作后的输出信息为:若是车辆到达,则输出汽车
*    在停车场内或便道上的停车位置;若是车辆离开,则输出汽车在停车场内停留的时间和
*    应交纳的费用(在便道上停留的时间不收费)。注意:栈采用顺序存储结构,队列采用环形
*    队列。
*        还需设一个临时栈,用于临时停放为要给离开的汽车让路而从停车场退出来的汽车,
*    也用顺序结构实现。
*    用户输入的命令有以下5种:
*    1、汽车到达
*    2、汽车离开
*    3、输出停车场中的所有汽车牌号
*    4、输出候车场中的所有汽车牌号
*    5、退出系统
*/

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>

#define N 3 // 停车场内最多的停车数
#define M 4 // 候车场内最多的停车数入队
#define PRICE 2 // 每单位停车费用

/*---------------------停车场:栈采用顺序存储结构--------------------*/
typedef struct
{
    int car_no[N]; // 车牌号
    int car_time[N]; // 进场时间
    int top; // 栈顶指针
}SqStack; // 声明顺序栈类型

/*------------------------候车场:队列采用环形队列-------------------*/
typedef struct
{
    int car_no[M]; // 车牌号
    int que_front; // 队头指针
    int que_rear; // 队尾指针
}SqQueue; // 声明环形队列类型

/*------------------------栈的运算算法-------------------*/
/*------------------------初始化栈-------------------*/
static void init_stack(SqStack *&s) // 指针的引用
{
    s = (SqStack *)malloc(sizeof(SqStack)); // 动态分配存储空间
    s->top = -1;
}

/*------------------------判断栈空-------------------*/
static bool stack_empty(SqStack *s)
{
    return (s->top == -1);
}

/*------------------------判断栈满-------------------*/
static bool stack_full(SqStack *s)
{
    return (s->top == N - 1);
}

/*------------------------压栈-------------------*/
static bool push(SqStack *&s, int car_no, int car_time)
{
    if(s->top == N - 1) // 栈满的情况
        return false;

    s->top++;
    s->car_no[s->top] = car_no; // 车牌号
    s->car_time[s->top] = car_time; // 进场时间

    return true;
}

/*------------------------出栈-------------------*/
static bool pop(SqStack *&s, int &car_no, int &car_time) // 指针的引用
{
    if(s->top == -1) // 栈空的情况
        return false;

    car_no = s->car_no[s->top]; // 提取车牌号
    car_time = s->car_time[s->top]; // 提取进场时间
    s->top--;

    return true;
}

/*------------------------显示栈中元素-------------------*/
static void display_stack(SqStack *s)
{
    int i;

    for(i = s->top; i >= 0; i--)
        printf("%d ", s->car_no[i]);

    printf("\n");
}

/*------------------------队列的运算算法-------------------*/
/*------------------------初始化队列-------------------*/
static void init_queue(SqQueue *&q) // 指针的引用
{
    q = (SqQueue *)malloc(sizeof(SqQueue)); // 动态分配存储空间
    q->que_front = q->que_front = 0;
}

/*------------------------判断队列空-------------------*/
static bool queue_empty(SqQueue *q)
{
    return (q->que_front == q->que_rear);
}

/*------------------------判断队列满-------------------*/
static bool queue_full(SqQueue *q)
{
    return ((q->que_rear + 1) % M == q->que_front);
}

/*------------------------入队操作-------------------*/
static bool en_queue(SqQueue *&q, int car_no)
{
    if((q->que_rear + 1) % M == q->que_front) // 队满
        return false;

    q->que_rear = (q->que_rear + 1) % M; // 计算队尾指针
    q->car_no[q->que_rear] = car_no;

    return true;
}

/*------------------------出队操作-------------------*/
static bool de_queue(SqQueue *&q, int &car_no)
{
    if(q->que_front == q->que_rear) // 队空的情况
        return false;

    q->que_front = (q->que_front + 1) % M; // 计算队头指针
    car_no = q->car_no[q->que_front]; // 提取车牌号

    return true;
}

/*------------------------显示队列中元素-------------------*/
static void display_queue(SqQueue *q)
{
    int i;

    i = (q->que_front + 1) % M;
    printf("%d ", q->car_no[i]);
    while((q->que_rear - i + M) % M > 0)
    {
        i = (i + 1) % M;
        printf("%d ", q->car_no[i]);
    }

    printf("\n");
}

int main(void)
{
    int command; // 输入的命令
    int i, j; // 循环变量
    int e1, e2;
    int car_no; // 车牌号
    int car_time; // 到达时间
    SqStack *st; // 停车场栈
    SqStack *tmp_st; // 临时栈
    SqQueue *qu; // 候车场队列

    init_stack(st);
    init_stack(tmp_st);
    init_queue(qu);
    do
    {
        printf(">输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):");
        scanf("%d", &command);
        switch(command)
        {
        case 1: // 汽车到达
            printf("   车牌号  到达时间:");
            scanf("%d %d", &car_no, &car_time);
            if(!stack_full(st)) // 停车场不满
            {
                push(st, car_no, car_time);
                printf("  停车场位置:%d\n", st->top + 1);
            }
            else // 停车场满
            {
                if(!queue_full(qu)) // 候车场不满
                {
                    en_queue(qu, car_no);
                    printf("  候车场位置:%d\n", qu->que_rear);
                }
                else
                    printf("  候车场已满,不能停车\n");
            }
            break;
        case 2: // 汽车离开
            printf("   车牌号  离开时间:");
            scanf("%d %d", &car_no, &car_time);
            for(i = 0; i <= st->top && st->car_no[i] != car_no; i++);
            if(i > st->top)
                printf("  未找到该编号的汽车\n");
            else
            {
                for(j = i; j <= st->top; j++)
                {
                    pop(st, e1, e2);
                    push(tmp_st, e1, e2); // 倒车到临时栈tmp_st中
                }
                pop(st, e1, e2); //该汽车离开
                printf("  %d汽车停车费用:%d\n", car_no, (car_time - e2) * PRICE);
                while(!stack_empty(tmp_st)) // 将临时栈tmp_st重新回到st中
                {
                    pop(tmp_st, e1, e2);
                    push(st, e1, e2);
                }
                if(!queue_empty(qu)) // 队不空时,将队头进栈st
                {
                    de_queue(qu, e1);
                    push(st, e1, car_time); // 以当前时间开始计费
                }
            }
            break;
        case 3: // 显示停车场情况
            if(!stack_empty(st))
            {
                printf("  停车场中的车辆:"); // 输出停车场中的车辆
                display_stack(st);
            }
            else
                printf("  停车场中无车辆\n");
            break;
        case 4: // 显示候车场情况
            if(!queue_empty(qu))
            {
                printf("  候车场中的车辆:"); // 输出候车场中的车辆
                display_queue(qu);
            }
            else
                printf("  候车场中无车辆\n");
            break;
        case 0: // 退出
            if(!stack_empty(st))
            {
                printf("  停车场中的车辆:"); // 输出停车场中的车辆
                display_stack(st);
            }
            if(!queue_empty(qu))
            {
                printf("  候车场中的车辆:"); // 输出候车场中的车辆
                display_queue(qu);
            }
            break;
        default: // 其它情况
            printf("   输入的命令错误\n");
            break;
        }
    }while(command != 0);

    return 0;
}
测试结果:

>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
   车牌号  到达时间:101 1
  停车场位置:1
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
   车牌号  到达时间:102 2
  停车场位置:2
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
   车牌号  到达时间:103 3
  停车场位置:3
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):1
   车牌号  到达时间:104 4
  候车场位置:1
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):3
  停车场中的车辆:103 102 101
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):4
  候车场中的车辆:104
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):2
   车牌号  离开时间:101 6
  101汽车停车费用:10
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):3
  停车场中的车辆:104 103 102
>输入命令(1:到达 2:离开 3:停车场 4:候车场 0:退出):0
  停车场中的车辆:104 103 102

猜你喜欢

转载自blog.csdn.net/xiezhi123456/article/details/86513330