练习

#include <stdio.h>
#include <time.h>
#include <stdlib.h>


#define MAXNUM 20 //停车场车位数
#define PRICE 2 //停车单价
//enum return_result{STACK_EMPTY,STACK_NO_EMPTY,STACK_FULL,STACK_NO_FULL,QUEUE_EMPTY,QUEUE_NO_EMPTY};
struct car
{
char num[10];//车牌号
struct tm intime;//进入时间
struct tm outtime;//离开时间
int price;//费用
int length;//停车时长
int position;//停车位
};
typedef struct car CAR;


typedef struct stack_data
{
CAR car[MAXNUM];//车辆信息
int top;//栈顶指针
}SeqStack;
void StackInit(SeqStack* s)//栈初始化
{
s->top = -1;
}
//判断栈是否为空
int IsStackEmpty(SeqStack* s)
{
if (s->top == -1)
return 1;
else
return 0;
}
//判断栈是否满
int IsStackFull(SeqStack* s)
{
if (s->top == MAXNUM - 1)
return 1;
else
return 0;
}


//入栈操作
void push_stack(SeqStack* s,CAR car)
{
if (!IsStackFull(s))//如果栈未满,则入栈
{
        s->top++;
   (s->car[s->top]) = car;//将车辆信息入栈
}
}
//出栈操作
CAR pop_stack(SeqStack* s,CAR car)
{
if(!IsStackEmpty(s))//栈不为空
{
car = s->car[s->top];
s->top--;
return car;
}
}
CAR stack_top(SeqStack* s,CAR car)//取栈顶元素
{
if(s->top != -1)
{
car = s->car[s->top];
return car;
}
}
//队列部分
struct carnode
{
CAR data;
struct carnode *next;
};
typedef struct carnode CarNodeType;//定义结点
typedef struct
{
CarNodeType *head;//头指针
CarNodeType *rear;//尾指针
}CarChainQueue;
//初始化队列
void ChainQueueInit(CarChainQueue *q)
{
    if(!(q->head = (CarNodeType*)malloc(sizeof(CarNodeType))))
{
printf("分配内存失败!退出!\n");
exit(0);
}
q->rear = q->head;
q->head->next = NULL;
q->rear->next = NULL;
}
//入队操作
void ChainQueueIn(CarChainQueue* q,CAR car)
{
    CarNodeType* p;
if (!(p = (CarNodeType*)malloc(sizeof(CarNodeType))));
{
printf("内存分配失败!退出!\n");
exit(0);
}
    p->data = car;
p->next = NULL;
q->rear->next = p;//先入队
q->rear = p;//再进1
}
//出队操作
CAR ChainQueueOut(CarChainQueue* q,CAR car)
{
    CarNodeType* p;
if (q->head != q->rear)//如果头尾指针不在一个位置,则可以进行出队操作
{
        p = q->head->next;
if (p->next == NULL)//队列中只有1个的情况
{
car = p->data;
q->rear = q->head;
free(p);
}
else
{
            q->head->next = p->next;
car = p->data;
free(p);
}
}
return car;
}
int IsChainQueueEmpty(CarChainQueue* q)//判断队列是否为空
{
if ( q->head == q->rear)
return 1;
else
return 0;
}
//时间显示函数(进入时间和离开时间)
void PrintDate(struct tm gm_date)//时间显示
{
printf("%d/%d %02d:%02d:%02d\n",gm_date.tm_mon,gm_date.tm_mday,gm_date.tm_hour+8,gm_date.tm_min,gm_date.tm_sec);//分别显示月,日,当前时间
//   time_t timep;
// time(&timep);
// printf("%s",ctime(&timep));
}
void ShowPark(SeqStack* s)//车位状态
{
struct tm gm_date;
int i;
printf("车位使用情况:\n");
if (IsStackEmpty(s))//如果栈空,则停车场中无车辆
printf("停车场中无车辆");
else
{
printf("位置\t车牌\t进站时间\n");
for( i = 0 ; i <= s->top ; i++)
{
printf("**********************************\n");
printf("%d\t",s->car[i].position);
printf("%s\t",s->car[i].num);
PrintDate(s->car[i].intime);//输出时间
}
printf("\t\t共有%d辆车",s->top+1);
if (s->top == MAXNUM - 1)
printf("停车场中已经无车位\n");
else
printf("还可以停放%d辆车\n",MAXNUM - 1 - (s->top));
printf("\n");
}
}
void ShowAisle(CarChainQueue* q)//显示过道状态
{
if( IsChainQueueEmpty(q) )
printf("过道上没有车辆\n");
else
{
        CarNodeType* p;//定义结点
p = q->head->next;//队列中的第一辆车
printf("\n过道使用状况:\n");
printf("车牌\t进入时间\n");
while( p != NULL )
{
            printf("%s\t",p->data.num);
PrintDate(p->data.intime);
p = p->next;
}
printf("****************************\n\n");
}
}
void ShowAll(SeqStack* s,CarChainQueue* q)//过道和车场的停车情况
{
    ShowPark(s);
ShowAisle(q);
}


void InPark(SeqStack* s,CarChainQueue* q)
{
CAR car;
struct tm *gm_date;
time_t seconds;
time(&seconds);
gm_date = gmtime(&seconds);//为了方便,以秒计


printf("车牌:\n");
scanf("%s",&car.num);
car.intime = *gm_date;//进入时间


if ((!IsStackFull(s)) && IsChainQueueEmpty(q))//如果停车场未满,且过道上没有车,则停入停车场
{
car.position = (s->top) +2;//栈底指针从-1开始,车位号
push_stack(s,car);//入栈
ShowPark(s);//输出现在停车场情况
}
else if(IsStackFull(s) || (!IsChainQueueEmpty(q)))//车位满且过道上有车
{
printf("停车场车位已满,请先将车停放在过道中\n");
car.position = MAXNUM;
ChainQueueIn(q,car);//进入队列


ShowAll(s,q);


}
}
void PrintRate(CAR *car)//计算离开时的费用状况
{
printf("\n    帐单:\n");
printf("*********************************\n");
printf("车牌:%s\n",car->num);
printf("停车位置:%d\n",car->position);
printf("进入时间:");
PrintDate(car->intime);
printf("\n");
printf("离开时间:");
PrintDate(car->outtime);
printf("\n");
printf("停车时间(秒):%d\n",car->length);
printf("费用(元):%d\n",car->price);
printf("*********************************\n");
printf("\n");
}
void OutPark(SeqStack* s,CarChainQueue* q)
{
struct tm *gm_date;
time_t seconds;
SeqStack tmp;//申请临时停车位
StackInit(&tmp);//初始化
char nowtime[10];//记录当前的时间
int i,pos;//pos为车辆离开的位置
CAR car;
if(IsStackEmpty(s))//栈空,则无车
{
printf("当前停车场内没有车辆。\n");
}
else
{
printf("当前车位的使用情况:\n");
        ShowPark(s);
printf("哪个车位的车要离开:\n");
        scanf("%d",&pos);
if (pos>0 && pos<=((s->top)+1))//输出车位号正确
{
            for (i = ((s->top)+1); i>pos ; i-- )
{
car = pop_stack(s,car);//出栈(将所有在pos位置后面的车辆)
car.position = car.position - 1;//修改变更后的车位号
push_stack(&tmp,car);//将车辆放入临时栈
}
car = pop_stack(s,car);//将目标车辆出栈
time(&seconds);
gm_date = gmtime(&seconds);//获取当前时间
car.outtime = *gm_date;//车辆离开时间
car.length = mktime(&car.outtime) - mktime(&car.intime);//mktime函数是将当前时间的秒数与1970年1月1日0时0分0秒作差所得的秒数
   car.price = (car.length/3600 + 1)*PRICE;
            PrintRate(&car);//输出车离开时的情况
while (!IsStackEmpty(&tmp))//当临时栈非空时
{
car = pop_stack(&tmp,car);//从临时栈中取出一辆车
push_stack(s,car);//将车放入栈中
}
while ( !IsStackFull(s) && !IsChainQueueEmpty(q))//如果栈未满且队列不空,则将队列中的车辆放入栈中
{
car = ChainQueueOut(q,car);//出队
time(&seconds);//车在队列中不计费,进入停车场时重新计时
gm_date = gmtime(&seconds);//记录当前时间
car.intime = *gm_date;
push_stack(s,car);//将车重新入栈
}
}
else//车位号输入错误
{
printf("车位号输入错误,或该车位没有车辆!\n");
}
}
}
int main()
{
     SeqStack Park;//停车场顺序栈
CarChainQueue Aisle;//过道队列
StackInit(&Park);
ChainQueueInit(&Aisle);
    char choise;
do
{
printf("********************************\n");
printf("停车场管理\n");
printf("1,车辆进入\n");
printf("2,车辆离开\n");
printf("3,查看停车场情况\n");
printf("4,退出\n");
printf("********************************\n");
printf("提示:本停车场有%d个车位,车位停满后的车辆将放在过道上。\n",MAXNUM);
printf("本停车场按小时收费,2元每小时,过道不收费。\n",PRICE);
printf("\n请选择操作:");
scanf(" %c",&choise);
switch (choise)
{
case '1':
InPark(&Park,&Aisle);
break;
case '2':
OutPark(&Park,&Aisle);
break;
case '3':
ShowAll(&Park,&Aisle);
break;
}
}while(choise != '4');
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值