C_Primer_Plus_Chapter17_exercise4

题目

Rewrite mall.c(Listing 17.7) so that it simulates a double booth having two queues.

解答

queue.h

c 复制代码
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include <stdbool.h>

typedef struct item
{
	long arrive;
	int processtime;
}Item;
#define MAXQUEUE 10
typedef struct node
{
	Item item;
	struct node * next;
} Node;
typedef struct queue
{
	Node * front; /* pointer to front of queue */
	Node * rear; /* pointer to rear of queue */
	int items; /* number of items in queue */
} Queue;
/* operation: initialize the queue */
/* precondition: pq points to a queue */
/* postcondition: queue is initialized to being empty */
void InitializeQueue(Queue * pq);
/* operation: check if queue is full */
/* precondition: pq points to previously initialized queue */
/* postcondition: returns True if queue is full, else False */
bool QueueIsFull(const Queue * pq);
/* operation: check if queue is empty */
/* precondition: pq points to previously initialized queue */
/* postcondition: returns True if queue is empty, else False */
bool QueueIsEmpty(const Queue *pq);
/* operation: determine number of items in queue */
/* precondition: pq points to previously initialized queue */
/* postcondition: returns number of items in queue */
int QueueItemCount(const Queue * pq);
/* operation: add item to rear of queue */
/* precondition: pq points to previously initialized queue */
/* item is to be placed at rear of queue */
/* postcondition: if queue is not empty, item is placed at */
/* rear of queue and function returns */
/* True; otherwise, queue is unchanged and */
/* function returns False */
bool EnQueue(Item item, Queue * pq);
/* operation: remove item from front of queue */
/* precondition: pq points to previously initialized queue */
/* postcondition: if queue is not empty, item at head of */
/* queue is copied to *pitem and deleted from */
/* queue, and function returns True; if the */
/* operation empties the queue, the queue is */
/* reset to empty. If the queue is empty to */
/* begin with, queue is unchanged and the */
/* function returns False */
bool DeQueue(Item *pitem, Queue * pq);
/* operation: empty the queue */
/* precondition: pq points to previously initialized queue */
/* postconditions: the queue is empty */
void EmptyTheQueue(Queue * pq);
#endif

queue.c

c 复制代码
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"

static void CopyToNode(Item item, Node * pn);

static void CopyToItem(Node * pn, Item * pi);

void InitializeQueue(Queue * pq)
{
	pq->front = pq->rear = NULL;
	pq->items = 0;
}
bool QueueIsFull(const Queue * pq)
{
	return pq->items == MAXQUEUE;
}
bool QueueIsEmpty(const Queue * pq)
{
	return pq->items == 0;
}
int QueueItemCount(const Queue * pq)
{
	return pq->items;
}
bool EnQueue(Item item, Queue * pq)
{
	Node * pnew;
	if (QueueIsFull(pq))
		return false;
	pnew = (Node *) malloc( sizeof(Node));
	if (pnew == NULL)
	{
		fprintf(stderr,"Unable to allocate memory!\n");
		exit(1);
	}
	CopyToNode(item, pnew);
	pnew->next = NULL;
	if (QueueIsEmpty(pq))
		pq->front = pnew; /* item goes to front */
	else
		pq->rear->next = pnew; /* link at end of queue */
	pq->rear = pnew; /* record location of end */
	pq->items++; /* one more item in queue */
	return true;
}

bool DeQueue(Item * pitem, Queue * pq)
{
	Node * pt;
	if (QueueIsEmpty(pq))
		return false;
	CopyToItem(pq->front, pitem);
	pt = pq->front;
	pq->front = pq->front->next;
	free(pt);
	pq->items--;
	if (pq->items == 0)
		pq->rear = NULL;
	return true;
}
/* empty the queue */
void EmptyTheQueue(Queue * pq)
{
	Item dummy;
	while (!QueueIsEmpty(pq))
		DeQueue(&dummy, pq);
}
/* Local functions */
static void CopyToNode(Item item, Node * pn)
{
	pn->item = item;
}
static void CopyToItem(Node * pn, Item * pi)
{
	*pi = pn->item;
}

mall.c

c 复制代码
// mall.c -- use the Queue interface
// compile with queue.c
#include <stdio.h>
#include <stdlib.h> // for rand() and srand()
#include <time.h> // for time()
#include "queue.h" // change Item typedef
#define MIN_PER_HR 60.0
bool newcustomer(double x); // is there a new customer?
Item customertime(long when); // set customer parameters
int main(void)
{
	Queue line1,line2;
	Item temp; // new customer data
	int hours,status,ch; 
	int perhour; // average # of arrivals per hour
	long cycle, cyclelimit; // loop counter, limit
	long turnaways = 0; // turned away by full queue
	long customers = 0; // joined the queue
	long served = 0; // served during the simulation
	long sum_line = 0; // cumulative line length
	int wait_time1 = 0; // time until Sigmund is free
	int wait_time2 = 0;
	double min_per_cust; // average time between arrivals
	long line_wait = 0; // cumulative time in line
	InitializeQueue(&line1);
	InitializeQueue(&line2);
	srand((unsigned int) time(0)); // random initializing of rand()
	puts("Case Study: Sigmund Lander's Advice Booths");
	puts("Enter the number of simulation hours in integer:");
	while((status = scanf("%d", &hours)) != 1 || hours<0 )
	{
		if(status==EOF)
		{
			puts("Encountered EOF");
			exit(1);
		}
		puts("Wrong input,try again:");
		while((ch=getchar())!='\n' && ch!=EOF)
			continue;
	}
	cyclelimit = MIN_PER_HR * hours;
	puts("Enter the average number of customers per hour in integer:");
	while((status=scanf("%d", &perhour))!=1 || perhour<=0)
	{
		if(status==EOF)
		{
			puts("Encountered EOF");
			exit(2);
		}
		puts("Wrong input,try again:");
		while((ch=getchar())!='\n' && ch!=EOF)
			continue;
	}
	min_per_cust = MIN_PER_HR / perhour;
	for (cycle = 0; cycle < cyclelimit; cycle++)
	{
		if (newcustomer(min_per_cust))
		{
			if (QueueIsFull(&line1)&&QueueIsFull(&line2))
				turnaways++;
			else if(QueueIsFull(&line1))
			{
				customers++;
				temp = customertime(cycle);
				EnQueue(temp, &line2);
			}
			else
			{
				customers++;
				temp = customertime(cycle);
				EnQueue(temp, &line1);
			}
		}
		if (wait_time1 <= 0 && (!QueueIsEmpty(&line1) || !QueueIsEmpty(&line2)))
		{
			if(QueueIsEmpty(&line1))
				DeQueue(&temp, &line2);
			else
				DeQueue(&temp, &line1);
			wait_time1 = temp.processtime;
			line_wait += cycle - temp.arrive;
			served++;
		}
		if (wait_time2 <= 0 && (!QueueIsEmpty(&line1) || !QueueIsEmpty(&line2)))
		{
			if(QueueIsEmpty(&line2))
				DeQueue(&temp, &line1);
			else
				DeQueue(&temp, &line2);
			wait_time2 = temp.processtime;
			line_wait += cycle - temp.arrive;
			served++;
		}
		if (wait_time1 > 0)
			wait_time1--;
		if (wait_time2 > 0)
			wait_time2--;
		sum_line += (QueueItemCount(&line1)+QueueItemCount(&line2));
	}
	if (customers > 0)
	{
		printf("customers accepted: %ld\n", customers);
		printf("customers served: %ld\n", served);
		printf("turnaways: %ld\n", turnaways);
		printf("average queue size: %.2f\n", (double) sum_line / cyclelimit);
		printf("average wait time: %.2f minutes\n",(double) line_wait / served);
	}
	else
		puts("No customers!");
	EmptyTheQueue(&line1);
	EmptyTheQueue(&line2);
	puts("Bye!");
	
	return 0;
}
// x = average time, in minutes, between customers
// return value is true if customer shows up this minute
bool newcustomer(double x)
{
	if (rand() * x / RAND_MAX < 1)
		return true;
	else
		return false;
}
// when is the time at which the customer arrives
// function returns an Item structure with the arrival time
// set to when and the processing time set to a random value
// in the range 1 - 3
Item customertime(long when)
{
	Item cust;
	cust.processtime = rand() % 3 + 1;
	cust.arrive = when;
	return cust;
}
相关推荐
小大宇2 小时前
Vue知识点-setup语法糖
1024程序员节
嘶哈哈哈2 小时前
PX4 + Livox MID360 + FAST-LIO + MAVROS
1024程序员节
Zevalin爱灰灰2 小时前
Linux入门第一部分(Ubuntu入门篇) 第二章 浅尝Ubuntu(一)
linux·嵌入式·1024程序员节
java_logo2 小时前
Docker 部署 Bililive-go:轻松搭建多平台直播录制
docker·1024程序员节·直播录制·轩辕镜像·bililive-go·chigusa/bililive-go
番茄味城市甜菜2 小时前
数据结构:单链表(C语言)
数据结构·链表·1024程序员节
java_nnnn2 小时前
Linux 学习第二篇:从零认识 Linux 文件系统、目录结构与基本命令
linux·运维·学习·1024程序员节
重生之我是Java开发战士2 小时前
【Redis】Redis五大数据类型
1024程序员节
一尺之棰2 小时前
DSP-定时器原理
1024程序员节
全栈小52 小时前
【C#】体验和使用墨衍MoGrow平台写一篇技术总结文章,提供C#,Quart.Net,统一捕获异常,定时任务关键词,看看出来效果如何
1024程序员节