c primer plus 第十七章课后编程4题

//接口文件定义
#ifndef QUEUE_H
#define QUEUE_H
#include <stdbool.h>
//在这里插入Item类型的定义,例如
typedef struct item {
long arrive; //一位顾客加入队列的时间
int processtime; //该顾客咨询时话费的时间
}Item; //用于use_q.c
//或者 typedef struct item {int gumption; int charisma;} Item;

#define MAXQUEUE 10

typedef struct node {
Item item;
struct node *next;
}Node;

typedef struct queue {
Node *front; /指向队列首项的指针/
Node *rear; /指向队列末尾的指针/
int items; /队列中的项/
}Queue;

/*操作: 初始化队列
前提条件: pq指向一个队列
后置条件: 队列被初始化为空 */
void InitializeQueue(Queue *pq);

/*操作: 检查队列是否已满
前提条件: pq指向之前被初始化的队列
后置条件: 如果队列已满返回true,否则返回false */
bool QueueIsFull(const Queue *pq);

/*操作: 检查队列是否为空
前提条件: pq指向之前被初始化的队列
后置条件: 如果队列为空则返回true, 否则返回false */
bool QueueIsEmpty(const Queue *pq);

/操作: 确定队列中的项
前提条件: pq指向之前被初始化的队列
后置条件: 返回队列中的项数。
/
int QueueItemCount(const Queue *pq);

/*操作: 在队列末尾添加项
前置条件: pq指向被初始化的队列
item是要被添加在队列末尾的项
后置条件: 如果队列不为空, item将被添加在队列的末尾,
该函数返回true,否则,队列不改变,函数返回false */
bool EnQueue(Item item, Queue *pq);

/*操作: 从队列的开头删除项
前提条件: pq指向之前被初始化的队列
后置条件: 如果队列不为空,队列首端的item将被拷贝到 *pitem中
并被删除,且函数返回true,
如果该操作使得队列为空,则重置队列为空
如果队列在操作前为空,该函数返回false */
bool DeQueue(Item *pitem, Queue *pq);

/*操作: 清空队列
前提条件: pq指向之前被初始化的队列
后置条件: 队列被清空。 */
void EmptyTheQueue(Queue *pq);

#endif /* queue_h */

//接口文件函数定义
#ifndef QUEUE_H
#define QUEUE_H
#include <stdbool.h>
//在这里插入Item类型的定义,例如
typedef struct item {
long arrive; //一位顾客加入队列的时间
int processtime; //该顾客咨询时话费的时间
}Item; //用于use_q.c
//或者 typedef struct item {int gumption; int charisma;} Item;

#define MAXQUEUE 10

typedef struct node {
Item item;
struct node *next;
}Node;

typedef struct queue {
Node *front; /指向队列首项的指针/
Node *rear; /指向队列末尾的指针/
int items; /队列中的项/
}Queue;

/*操作: 初始化队列
前提条件: pq指向一个队列
后置条件: 队列被初始化为空 */
void InitializeQueue(Queue *pq);

/*操作: 检查队列是否已满
前提条件: pq指向之前被初始化的队列
后置条件: 如果队列已满返回true,否则返回false */
bool QueueIsFull(const Queue *pq);

/*操作: 检查队列是否为空
前提条件: pq指向之前被初始化的队列
后置条件: 如果队列为空则返回true, 否则返回false */
bool QueueIsEmpty(const Queue *pq);

/操作: 确定队列中的项
前提条件: pq指向之前被初始化的队列
后置条件: 返回队列中的项数。
/
int QueueItemCount(const Queue *pq);

/*操作: 在队列末尾添加项
前置条件: pq指向被初始化的队列
item是要被添加在队列末尾的项
后置条件: 如果队列不为空, item将被添加在队列的末尾,
该函数返回true,否则,队列不改变,函数返回false */
bool EnQueue(Item item, Queue *pq);

/*操作: 从队列的开头删除项
前提条件: pq指向之前被初始化的队列
后置条件: 如果队列不为空,队列首端的item将被拷贝到 *pitem中
并被删除,且函数返回true,
如果该操作使得队列为空,则重置队列为空
如果队列在操作前为空,该函数返回false */
bool DeQueue(Item *pitem, Queue *pq);

/*操作: 清空队列
前提条件: pq指向之前被初始化的队列
后置条件: 队列被清空。 */
void EmptyTheQueue(Queue *pq);

#endif /* queue_h */

//main()
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include “queue.h”
#define MIN_PER_HR 60.0

bool newcustomer(double x); //是否有新顾客到来?
Item customertime(long when); //设置顾客参数

int main(void)
{
srand((unsigned int) time(0)); //rand() 随机初始化
printf(“请输入每个摊位最多排多少人:”);
int hour;
scanf("%d", &hour);

Queue line1[hour];       //摊位1
Queue line2[hour];       //摊位2
InitializeQueue(line1);
InitializeQueue(line2);
Item temp1, temp2;              //1-2号摊位新顾客的数据
int hours;               //模拟的小时数
int perhour;             //每小时平均多少位顾客
long cycle, cyclelimit;  //循环计数器, 计数器的上限
long turnaways = 0;      //队列已满被拒绝的顾客数量
long customers = 0;      //加入队列的顾客数量
long served = 0;         //在模拟期间咨询过Sigmund的顾客数量
long sum_line1 = 0;       //累计的队列1总长
long sum_line2 = 0;
long wait_time1 = 0;      //从当前到Sigmund空闲所需的时间
long wait_time2 = 0;
double min_per_cust;     //顾客到来的平均时间
long line_wait1 = 0;      //队列1累计的等待时间
long line_wait2 = 0;
printf("请输入需要测试的时长:");
scanf("%d",&hours);
cyclelimit = MIN_PER_HR * hours;
printf("请输入每个小时平均到来的顾客数:");
scanf("%d", &perhour);
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
            {
                customers++;
                if(QueueItemCount(line2) > QueueItemCount(line1) || QueueIsFull(line1))
                {
                    temp1 = customertime(cycle);
                    EnQueue(temp1, line1);
                }
                else
                {
                    temp2 = customertime(cycle);
                    EnQueue(temp2, line2);
                }
              
            }
            if (wait_time1 <= 0 && !QueueIsEmpty(line1))
            {
                DeQueue(&temp1, line1);
                wait_time1 = temp1.processtime;
                line_wait1 += cycle - temp1.arrive;
                served++;
            }
            if (wait_time2 <= 0 && !QueueIsEmpty(line2))
            {
                DeQueue(&temp2, line2);
                wait_time2 = temp2.processtime;
                line_wait2 += cycle - temp2.arrive;
                served++;
            }
        }
        if(wait_time1 > 0)
            wait_time1--;
        sum_line1 += QueueItemCount(line1);
        if(wait_time2 > 0)
            wait_time2--;
        sum_line2 += 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_line1 + sum_line2) / cyclelimit /2);
        printf(" average wait time: %.2f minutes\n",
               (double) (line_wait1 + line_wait2) / served /2);
    }
    else
        puts("No customers!");
    EmptyTheQueue(line1);
    EmptyTheQueue(line2);
puts("Bye!");

return 0;

}

//X是顾客到来的平均时间(单位: 分钟)
//如果1分钟内有顾客到来,则返回true
bool newcustomer(double x)
{
if(rand() *x/RAND_MAX < 1)
return true;
else
return false;
}

//when是顾客到来的时间
//该函数返回一个Item结构,该顾客到达的时间设置为when.
//咨询时间设置为1~3的随机值
Item customertime(long when)
{
Item cust;

cust.processtime = rand()%3+1;
cust.arrive = when;

return cust;

}

发布了85 篇原创文章 · 获赞 1 · 访问量 1889

猜你喜欢

转载自blog.csdn.net/Tekkenwxp/article/details/104499313