球钟问题

文章介绍了一个使用栈和队列数据结构模拟球钟时间记录的系统。通过一个27球的队列和三个不同容量的栈(分钟、五分钟、小时),每过一分钟,系统会根据规则移动球以更新时间显示。代码实现包括栈和队列的创建、入栈、出栈等操作,以及主程序中的时间推进逻辑。
摘要由CSDN通过智能技术生成

问题描述:

球钟是利用球的移动来记录时间的装置

它有三个可以容纳若干个球的容器:分钟指示器,五分钟指示器,小时指示器。

若分钟指示器中有2个球,5分钟指示器中有3个球,小时指示器中有4个球,则时间为4:17。

每过一分钟,球钟就会从球队列的队首取出一个球放入分钟指示器,分钟指示器最多可容纳4个球。在放进去第五个球的时候,分钟指示器内的4个球就会按照他们被放入时的相反顺序加入球队列的队尾。而第五个球就会进入五分钟指示器。按此类推,五分钟指示器最多可放11个球,小时指示器最多可放11个球。因此,该球种表示的时间范围是从00:00到11:59

思考方式:

设置一个容纳27个球的队列,装满带有序号的球(给队列每一项赋值)

然后设置三个栈,1分钟的栈容量为5,5分钟的栈和1小时的栈容量都为12.

每过1分钟,如果栈没满就从队列中取出一个球,装入栈,如果栈满则将栈里的球出栈,装回队列,再将球装入进一位的栈,依次这样判断,这样就能实现球钟的同时,球的顺序不变。

实现函数:

stack.h

#ifndef _STACK_H_
#define _STACK_H_

#define MEM 12    //栈1的成员数为12
#define mem 5     //栈2的成员数为5
typedef int data_t;
typedef struct STACK   //建立1小时和五分钟的指示栈,即栈1
{
    data_t data[MEM];
    int top;
}stack_hour_t;
typedef struct STACK2     //建立1分钟的指示栈,即栈2
{
    data_t data[mem];
    int top;
}stack_min_t;


stack_hour_t *stackhourCreate();    //栈1创建函数

//栈1的出栈和入栈
int stackhour_En(stack_hour_t *clock, int i);
int stackhour_De(stack_hour_t *clock);
//栈1的判满和判空
int stackhourIsFull(stack_hour_t *clock);
int stackhourIsEmpty(stack_hour_t *clock);


stack_min_t *stackminCreate();      //栈2创建函数

//栈2的出栈和入栈
int stackmin_En(stack_min_t *clock, int i);
int stackmin_De(stack_min_t *clock);
//栈2的判满和判空
int stackminIsFull(stack_min_t *clock);
int stackminIsEmpty(stack_min_t *clock);

#endif

stack.c

#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

stack_hour_t *stackhourCreate()
{
    stack_hour_t *hour = (stack_hour_t *)malloc(sizeof(stack_hour_t));

    if(NULL == hour)
        return NULL;

    hour->top = 0;
    return hour;
}

stack_min_t *stackminCreate()
{
    stack_min_t *min = (stack_min_t *)malloc(sizeof(stack_min_t));

    if(NULL == min)
        return NULL;

    min->top = 0;
    return min;
}

int stackhourIsFull(stack_hour_t *clock)
{
    if(NULL == clock)
        return -1;
    return clock->top == MEM-1;
}

int stackminIsFull(stack_min_t *clock)
{
    if(NULL == clock)
        return -1;
    return clock->top == mem-1;
}

int stackhour_En(stack_hour_t *clock, int i)
{
    if(NULL == clock)
        return -1;
    if(stackhourIsFull(clock))
        return 1;

    clock->data[clock->top] = i;
    clock->top ++;
    return 0;
}

int stackmin_En(stack_min_t *clock, int i)
{
    if(NULL == clock)
        return -1;
    if(stackminIsFull(clock))
        return 1;

    clock->data[clock->top] = i;
    clock->top ++;
    return 0;
}

int stackhour_De(stack_hour_t *clock)
{
    if(NULL == clock)
        return -1;
    if(stackhourIsEmpty(clock))
        return -1;

    int tem = clock->data[clock->top];
    clock->top --;
    return tem;
}

int stackmin_De(stack_min_t *clock)
{
    if(NULL == clock)
        return -1;
    if(stackminIsEmpty(clock))
        return -1;

    int tem = clock->data[clock->top];
    clock->top --;
    return tem;
}

int stackhourIsEmpty(stack_hour_t *clock)
{
    if(NULL == clock)
        return -1;
    return clock->top == 0;
}

int stackminIsEmpty(stack_min_t *clock)
{
    if(NULL == clock)
        return -1;
    return clock->top == 0;
}

queue.h

#ifndef _QUEUE_H_
#define _QUEUE_H_

typedef int data_t;
#define SIZE 27   //队列总数为27
typedef struct node  //定义顺序队列
{
    data_t data[SIZE];
    int front;
    int rear;
}queue_t;



queue_t *ballCreate();   //存球的队列建立

//球的出队和入队
int ball_En(queue_t *ball, int i);
int ball_De(queue_t *ball);

//队列的判空和判满
int ballIsEmpty(queue_t *ball);
int ballIsFull(queue_t *ball);

#endif

queue.c

#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

queue_t *ballCreate()
{
    queue_t *ball = (queue_t *)malloc(sizeof(queue_t));

    if(NULL == ball)
        return NULL;

    ball->front = 0;
    ball->rear = 0;
    return ball;
}

int ball_En(queue_t *ball, int i)
{
    if(NULL == ball)
        return -1;
    if(ballIsFull(ball))
        return -1;

    ball->data[ball->rear] = i;
    ball->rear = (ball->rear + 1) % SIZE;
    return 0;
}

int ball_De(queue_t *ball)
{
    if(NULL == ball)
        return -1;
    if(ballIsEmpty(ball))
        return -1;

    int tem = ball->data[ball->front];
    ball->front = (ball->front + 1) % SIZE;
    return tem;
}

int ballIsEmpty(queue_t *ball)
{
    if(NULL == ball)
        return -1;
    return ball->front == ball->rear;
}

int ballIsFull(queue_t *ball)
{
    if(NULL == ball)
        return -1;
    return ball->front == (ball->rear + 1)%SIZE;
}

main.c

#include <stdio.h>
#include <unistd.h>
#include "queue.h"
#include "stack.h"

int main(int argc, char *argv[])
{ 
    //创建球
    queue_t *ball = ballCreate();
    if(NULL == ball)
        return -1;
    int i = 0;

    //给球排序
    while(!ballIsFull(ball))
    {
        ball_En(ball,i);
        i++;
    }
    /*
    printf("球的初始顺序为:");
    for(int x=0;x<SIZE-1;x++)
        printf("%d ",ball->data[x]);
    puts("");
    */

    //创建1分钟指示
    stack_min_t *min1 = stackminCreate();
    //创建5分钟指示
    stack_hour_t *min5 = stackhourCreate();
    //创建1小时指示
    stack_hour_t *hour = stackhourCreate();

    while(1)
    {
        printf("%d点%d分\n",hour->top,min5->top * 5 + min1->top); //打印球钟时间


        //sleep(1);//每过去1秒程序过去1分钟
        sleep(60);   //每分钟记一分钟


        if(stackminIsFull(min1))//过去1分钟
        {
            for(min1->top;min1->top>=0;min1->top--) //判满时对栈清空
                ball_En(ball, stackmin_De(min1));
            min1->top++;
            if(stackhourIsFull(min5))//过去5分钟
            {
                for(min5->top;min5->top>=0;min5->top--)
                    ball_En(ball, stackhour_De(min5));
                min5->top++;
                if(stackhourIsFull(hour))//过去1小时
                {
                    for(hour->top;hour->top>=0;hour->top--)
                        ball_En(ball, stackhour_De(hour));
                    hour->top++;
                }else{
                    stackhour_En(hour, ball_De(ball));
                }
            }else{
                stackhour_En(min5, ball_De(ball));
            }
        }else
        {
            stackmin_En(min1, ball_De(ball));  //入栈一个球
        }
    }

    return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值