球钟问题描述:球钟是一个利用球的移动来记录时间的简单装置。它有三个可以容纳若干个球的指示器:分钟指示器,五分钟指示器,小时指示器。若分钟指示器中有2个球,5分钟指示器中有6个球,小时指示器中有5个球,则时间为5:32。
这里的栈是使用的链式存储实现的,具体的思想请看本人的前几个帖子。
这里的栈实现是使用的连续存储实现的,具体的思想比较简单,就不多说了。
stack.h:
下面请看最关键的主函数的实现:
其中的debug函数是为了方便调试而设置的,并且可以用它来打印每隔12个小时的队列情况
这个问题看似很难,其实用计算机程序来实现的话是不难的,只要找到基本规律,然后用循环让计算机不停地去做就可以了。
工作原理:每过一分钟,球钟就会从球队列的队首取出一个球放入分钟指示器,分钟指示器最多可容纳4个球。当放入第五个球时,在分钟指示器的4个球就会按照他们被放入时的相反顺序加入球队列的队尾。而第五个球就会进入分钟指示器。按此类推,五分钟指示器最多可放11个球,小时指示器最多可放11个球。当小时指示器放入第12个球时,原来的11个球按照他们被放入时的相反顺序加入球队列的队尾,然后第12个球也回到队尾。这时,三个指示器均为空,回到初始状态,从而形成一个循环。因此,该秋种表示的时间范围是从00:00到11:59
请看示意图(图是从网上找的,不好勿喷啊!!):
思考:
要想表示00:00到12:00需要多少个球?假设,指示器都为空,球队列需要多长时间能回到原来的状态?
答案是总共组要27个球,当每个指示器满的时候,为了保证队列不为空,所以为4+11+11+1=27。下面解决第二个问题:
这里我为了管理方便,采用了make工程管理器,总共有以下几个文件:
main.c queue.c stack.c queue.h stack.h Makefile
这里的main文件不用说,肯定就是主函数,而stack.c和queue.c是分别定义栈和队列操作的函数,而两个头文件是定义这些函数的接口。
搞清楚了文件之间的关系后,请看源码:
queue.c文件:
- <span style="font-family:SimSun;font-size:12px;">/*************************************************************************
- > File Name: queue.c
- > Author: Baniel Gao
- > Mail: createchance@163.com
- > Blog: blog.youkuaiyun.com/createchance
- > Created Time: 2013年12月21日 星期六 11时13分10秒
- ************************************************************************/
- #include "queue.h"
- linkqueue_st *linkqueue_init(int size)
- {
- linkqueue_st *queue = NULL;
- queue = (linkqueue_st *)malloc(sizeof(linkqueue_st));
- queue->total = size;
- queue->current = 0;
- queue->head = linkqueue_node_create(0);
- queue->tail = queue->head;
- return queue;
- }
- nodequeue_st *linkqueue_node_create(int value)
- {
- nodequeue_st *node = NULL;
- node = (nodequeue_st *)malloc(sizeof(nodequeue_st));
- node->data = value;
- node->next = NULL;
- return node;
- }
- int linkqueue_enqueue(linkqueue_st *queue, int value)
- {
- nodequeue_st *new = NULL;
- if(linkqueue_isfull(queue))
- return -1;
- new = linkqueue_node_create(value);
- queue->tail->next = new;
- queue->tail = new;
- queue->current++;
- return 0;
- }
- int linkqueue_dequeue(linkqueue_st *queue, int *value)
- {
- nodequeue_st *tmp;
- if(linkqueue_isempty(queue))
- return -1;
- tmp = queue->head;
- *value = tmp->next->data;
- queue->head = tmp->next;
- free(tmp);
- queue->current--;
- return 0;
- }
- int linkqueue_isfull(linkqueue_st *queue)
- {
- if(queue->current == queue->total)
- return 1;
- return 0;
- }
- int linkqueue_isempty(linkqueue_st *queue)
- {
- if(queue->current == 0)
- return 1;
- return 0;
- }
- int linkqueue_free(linkqueue_st *queue)
- {
- nodequeue_st *p = queue->head;
- nodequeue_st *tmp;
- while(p != NULL) {
- tmp = p;
- p = p->next;
- free(tmp);
- }
- free(queue);
- return 0;
- }</span>
这里的栈是使用的链式存储实现的,具体的思想请看本人的前几个帖子。
stack.c:
- <span style="font-family:SimSun;font-size:12px;">/*************************************************************************
- > File Name: stack.c
- > Author: Baniel Gao
- > Mail: createchance@163.com
- > Blog: blog.youkuaiyun.com/createchance
- > Created Time: 2013年12月21日 星期六 11时13分18秒
- ************************************************************************/
- #include "stack.h"
- seqstack_st *seqstack_init(int size)
- {
- seqstack_st *stack = NULL;
- stack = (seqstack_st *)malloc(sizeof(seqstack_st));
- stack->total = size;
- stack->top = 0;
- stack->data = (int *)malloc(sizeof(int) * size);
- return stack;
- }
- int seqstack_push(seqstack_st *stack, int value)
- {
- if(seqstack_isfull(stack))
- return -1;
- stack->data[stack->top++] = value;
- return 0;
- }
- int seqstack_pop(seqstack_st *stack, int *value)
- {
- if(seqstack_isempty(stack))
- return -1;
- *value = stack->data[--stack->top];
- return 0;
- }
- int seqstack_isfull(seqstack_st *stack)
- {
- if(stack->top == stack->total)
- return 1;
- return 0;
- }
- int seqstack_isempty(seqstack_st *stack)
- {
- if(stack->top == 0)
- return 1;
- return 0;
- }
- int seqstack_free(seqstack_st *stack)
- {
- free(stack->data);
- free(stack);
- return 0;
- }</span>
这里的栈实现是使用的连续存储实现的,具体的思想比较简单,就不多说了。
两个头文件:
queue.h:
- <span style="font-family:SimSun;font-size:12px;">/*************************************************************************
- > File Name: queue.h
- > Author: Baniel Gao
- > Mail: createchance@163.com
- > Blog: blog.youkuaiyun.com/createchance
- > Created Time: 2013年12月21日 星期六 12时01分54秒
- ************************************************************************/
- #ifndef _QUEUE_H_
- #define _QUEUE_H_
- #include <stdio.h>
- #include <stdlib.h>
- typedef struct _nodequeue_ {
- int data;
- struct _nodequeue_ *next;
- } nodequeue_st;
- typedef struct _linkqueue_ {
- int total;
- int current;
- nodequeue_st *head;
- nodequeue_st *tail;
- } linkqueue_st;
- linkqueue_st *linkqueue_init(int size);
- nodequeue_st *linkqueue_node_create(int value);
- int linkqueue_enqueue(linkqueue_st *queue, int value);
- int linkqueue_isfull(linkqueue_st *queue);
- int linkqueue_dequeue(linkqueue_st *queue, int *value);
- int linkqueue_isempty(linkqueue_st *queue);
- int linkqueue_free(linkqueue_st *queue);
- #endif</span>
stack.h:
- <span style="font-family:SimSun;font-size:12px;">/*************************************************************************
- > File Name: stack.h
- > Author: Baniel Gao
- > Mail: createchance@163.com
- > Blog: blog.youkuaiyun.com/createchance
- > Created Time: 2013年12月21日 星期六 11时58分18秒
- ************************************************************************/
- #ifndef _STACK_H_
- #define _STACK_H_
- #include <stdio.h>
- #include <stdlib.h>
- typedef struct _seqstack_ {
- int total;
- int top;
- int *data;
- } seqstack_st;
- seqstack_st *seqstack_init(int size);
- int seqstack_push(seqstack_st *stack, int value);
- int seqstack_isfull(seqstack_st *stack);
- int seqstack_pop(seqstack_st *stack, int *value);
- int seqstack_isempty(seqstack_st *stack);
- int seqstack_free(seqstack_st *stack);
- #endif</span>
下面请看最关键的主函数的实现:
main.c:
- <span style="font-family:SimSun;font-size:12px;">/*************************************************************************
- > File Name: main.c
- > Author: Baniel Gao
- > Mail: createchance@163.com
- > Blog: blog.youkuaiyun.com/createchance
- > Created Time: 2013年12月21日 星期六 11时13分24秒
- ************************************************************************/
- #include "queue.h"
- #include "stack.h"
- int queue_check(linkqueue_st *queue);
- void debug(linkqueue_st *queue);
- int main(void)
- {
- int timer = 0;
- int value = 1;
- int tmp;
- int queue_size = 27;
- int stack_m1_size = 4;
- int stack_m5_size = 11;
- int stack_h1_size = 11;
- linkqueue_st *queue;
- seqstack_st *stack_m1;
- seqstack_st *stack_m5;
- seqstack_st *stack_h1;
- queue = linkqueue_init(queue_size);
- stack_m1 = seqstack_init(stack_m1_size);
- stack_m5 = seqstack_init(stack_m5_size);
- stack_h1 = seqstack_init(stack_h1_size);
- while(-1 != linkqueue_enqueue(queue, value))
- value++;
- while(1) {
- linkqueue_dequeue(queue, &value);
- if(-1 != seqstack_push(stack_m1, value))
- continue;
- while(-1 != seqstack_pop(stack_m1, &tmp))
- linkqueue_enqueue(queue, tmp);
- if(-1 != seqstack_push(stack_m5, value))
- continue;
- while(-1 != seqstack_pop(stack_m5, &tmp))
- linkqueue_enqueue(queue, tmp);
- if(-1 != seqstack_push(stack_h1, value))
- continue;
- while(-1 != seqstack_pop(stack_h1, &tmp))
- linkqueue_enqueue(queue, tmp);
- linkqueue_enqueue(queue, value);
- timer++;
- debug(queue);
- if(queue_check(queue))
- break;
- }
- printf("The time is %d hours!\n", timer*12);
- linkqueue_free(queue);
- seqstack_free(stack_m1);
- seqstack_free(stack_m5);
- seqstack_free(stack_h1);
- return 0;
- }
- void debug(linkqueue_st *queue)
- {
- nodequeue_st *p = queue->head->next;
- while(p != NULL) {
- printf("%d ", p->data);
- p = p->next;
- }
- putchar('\n');
- }
- int queue_check(linkqueue_st *queue)
- {
- nodequeue_st *p = queue->head->next;
- while(p != NULL && p->next != NULL) {
- if(p->data > p->next->data)
- return 0;
- p = p->next;
- }
- return 1;
- }</span>
其中的debug函数是为了方便调试而设置的,并且可以用它来打印每隔12个小时的队列情况
下面是Makefile:
- <span style="font-family:SimSun;font-size:12px;">CC:= gcc
- CFLAGS:= -Wall -O2 -c
- OBJ:= ballclock
- .PHONY: clean memcheck
- $(OBJ): main.o stack.o queue.o
- $(CC) -o $@ $^
- main.o: main.c stack.h queue.h
- $(CC) -o $@ $< $(CFLAGS)
- queue.o: queue.c queue.h
- $(CC) -o $@ $< $(CFLAGS)
- stack.o: stack.c stack.h
- $(CC) -o $@ $< $(CFLAGS)
- clean:
- rm -rf *.o $(OBJ)
- memcheck:
- valgrind --tool=memcheck ./$(OBJ)</span>
这个问题看似很难,其实用计算机程序来实现的话是不难的,只要找到基本规律,然后用循环让计算机不停地去做就可以了。
运行结果是552个小时,也就是23天!!
原文出处:http://blog.youkuaiyun.com/createchance/article/details/17466053