【问题描述】设计速冻食品厂的冷库管理系统。主要功能是入库操作和出库操作。
速冻食品厂冷库管理的特点:先入库的产品必须先出库。当天入库的不得出库。
管理对象:速冻箱号。设共有n个速冻箱,循环使用。
【主要功能】
要求设计算法实现以下操作功能:
- 入库操作:指定产品数量(以盘为单位),检查空箱数量是否足够。
- 出库操作:指定产品数量,检查入库时间以及产品数量是否足够。
- 查询操作:返回库中的产品数量,入库时间最长的产品数量和存放天数。
- 菜单选择上述操作及退出。
主程序执行时循环显示菜单,用户选择后,转入相应功能函数中。功能函数执行完毕返回主程序后仍保持菜单状态,直到选择退出。
【数据结构】
使用一维数组foodbox[MaxSize]表示速冻箱集合,下标表示速冻箱号,值为入库日期值(模拟)。
建立一个循环队列q [MqSize],用于控制产品的入库和出库顺序,以及速冻箱的循环使用。
【算法提示】
产品放入一个速冻箱入库时,该箱号入队;产品出库时,该箱号出队。队列长度即为库中产品数量。
队列qu的最大存储空间MqSize可以小于foodbox的空间MaxSize。假设一天的最大产量为50箱,而出库速度与入库速度在某一天内可能不同,则队列的存储空间MqSize应大于50。请自行设计各参数值。
题目分析:
这道题说实话没有完全看懂,尤其是前面标红部分的产品以盘为单位,但是到了后面红色部分为什么箱子构成的队列队列长度变成了产品数量呢?题作者想要表达的情景可能我没有完全理解,这里就按照我自己的理解分析这道题:我们生产好产品后将产品装好放进箱子中,每个箱子中可以存放若干件产品(私以为这样的结构才符合现实,也更有意义),然后我们将该箱子放入冷库中并记录放入时间,到了出库时,按照队列的原则,先进队的也先出队。
按照我的理解:如果有三个箱子,里面分别有产品 10 20 30 盘,当我们需要20个产品时,我们需要遵循先进先出的原则,从第一个箱子中拿出全部10盘产品同时从第二个箱子中取出10盘产品,这是符合队列的原则同时亦是符合实际情况需要的,这样的话在队列中具体表现就是一号箱子出队同时二号箱子将数据更新为10,然后我们又空余下来了一号箱子,可以在入库时对他进行重新使用。
下面是代码实现
首先是复用了原先的循环队列:
#include<iostream>
using namespace std;
#define ERROR 0
#define OK 1
#define MAXQSIZE 100
typedef int QElemType;
typedef int Status;
//队列的顺序存储结构
class SqQueue
{
friend class System;
QElemType* base; //存储空间的基地址
int front; //头指针
int rear; //尾指针
public:
bool InitQueue(int boxNum=MAXQSIZE); //初始化队列
bool EnQueue(QElemType); //入队
bool DeQueue(QElemType&); //出队
void GetHead(int& t); //取队头元素
bool QueueTraverse(); //遍历队列
int QueueLength(); //队列长度
};
//循环队列的初始化
bool SqQueue::InitQueue(int boxNum){//构造一个空队列Q
base = new QElemType[boxNum];
if (!base)
exit(OVERFLOW); //存储分配失败
front = rear = 0;
return OK;
};
//循环队列的入队
bool SqQueue::EnQueue(QElemType e)
{//插入元素e为Q的新的队尾元素
if ((rear + 1) % MAXQSIZE == front)
return ERROR; //尾指针在循环意义上加1后等于头指针,表明队满
base[rear] = e;
rear = (rear + 1) % MAXQSIZE;
return OK;
}
//循环队列的出队
bool SqQueue::DeQueue(QElemType& e)
{//删除Q的队头元素,用e返回其值
if (front == rear)
return ERROR;
e = base[front];
front = (front + 1) % MAXQSIZE;
return OK;
}
//取循环队列的队头元素
void SqQueue::GetHead(int &t)
{//返回Q的队头元素,不修改队头指针
if (front != rear) //队列非空
t=base[front]; //返回队头元素的值,队头指针不变
}
//遍历输出循环队列
bool SqQueue::QueueTraverse()
{
cout << "当前队列为:";
int f = front;
int r = rear;
if (f == r)
return ERROR;
while (f != r) //队列非空
{
cout << base[f] << " ";
f = (f + 1) % MAXQSIZE;
}
cout << endl;
return 1;
}
//求循环队列长度
int SqQueue::QueueLength()
{
//返回Q的元素个数
int len = (rear - front + MAXQSIZE) % MAXQSIZE;
return len;
}
然后是在此基础上冷库管理系统的具体实现:
#pragma once
#include"sqList.h"
#include<Windows.h>
class System {
SqQueue Q;
int boxNum; //箱子数量
string date[MAXQSIZE]; //入库时间
public:
System() {
cout << "请输入速冻箱数量:";
cin >> boxNum;
Q.InitQueue(boxNum);
cout << endl << "系统初始化完成,现有速冻箱" << boxNum << "个" << endl;
}
void inBox(); //入库操作
void outBox(); //出库操作
void find(); //查询操作
void menu(); //菜单
void endFunc(); //结束操作
};
///结束操作//
void System::endFunc() {
cout << "输入“1”返回菜单或输入其他退出系统:" << endl;
int a;
cin >> a;
switch (a)
{
case(1):
menu();
break;
default:
break;
}
}
///end of 结束操作///
/入库操作实现///
void System::inBox() {
if (Q.QueueLength() == boxNum)
cout << "已无空速冻箱,无法入库" << endl;
else {
cout << "使用"<< Q.rear%boxNum<<"号速冻箱:" << endl;
cout << "请输入放入产品数量:";
int n;
cin >> n;
cout << endl << "请输入入库时间:";
cin >> date[Q.rear];
cout << endl;
Q.EnQueue(n);
cout << "入库成功!" << endl;
}
endFunc();
}
///end of 入库操作实现//
//出库操作实现
void System::outBox() {
if (Q.front == Q.rear)
cout << "当前库中无产品!" << endl;
else {
int sum=0; //统计有多少产品可以出库
int need;
string nowDate;
cout << "输入需要产品数量:" ;
cin >> need;
cout << "输入当前日期:";
cin >> nowDate;
int f = Q.front;
int r = Q.rear;
while (f != r&&nowDate>date[f]) //队列非空,且未达到当前日期
{
sum += Q.base[f];
if (sum >= need)
break;
f = (f + 1) % MAXQSIZE;
}
if (sum >= need)
{
cout << "产品数量足够,是否确认出库?" << endl;
cout << "1.确认"<<" \t其他:取消"<<endl;
bool a;
int sumed=0; //统计已经出队元素
int out; //用于接受出队元素
cin >> a;
if (a == 1) {
for (int i = Q.front; i <= f; i++) {
if (i != f) {
Q.DeQueue(out);
sumed += out;
}
else {
if((need - sumed)==Q.base[i])
Q.DeQueue(out);
else {
Q.base[i] = Q.base[i] - (need - sumed);
}
}
}
cout << "出库成功!";
}
}
else {
cout << "符合条件的产品不足!" << endl;
}
}
endFunc();
}
///end of 出库操作///
///查询操作/
void System::find() {
cout << "系统中当前有产品:" ;
int sum=0;
int f = Q.front;
int r = Q.rear;
while (f != r ) //队列非空,且未超过当前时间
{
sum += Q.base[f];
f = f + 1;
}
cout << sum <<"件" << endl;
cout << "当前存储情况如下:" << endl;
cout << "箱号\t产品数\t存入日期" << endl;
f = Q.front;
r = Q.rear;
while (f != r) //队列非空
{
cout << f%boxNum<<'\t';
cout << Q.base[f] << '\t';
cout << date[f]<<'\t'<<endl;
f = f + 1;
}
cout << endl;
endFunc();
}
end of 查询操作/
///菜单/
void System::menu() {
system("cls");
cout << "当前系统有速冻箱 " << boxNum << " 个" << endl;
cout << "当前系统已占用速冻箱 " << Q.QueueLength() << " 个" << endl;
cout << "*********************************" << endl;
cout << "*\t请输入数字选择所需功能\t*" << endl;
cout << "*\t1:入库\t\t\t*" << endl;
cout << "*\t2:出库\t\t\t*" << endl;
cout << "*\t3:查询\t\t\t*" << endl;
cout << "*\t9:退出系统\t\t*" << endl;
cout << "*********************************" << endl;
cout << "请输入数字选择功能:";
int k;
cin >> k;
switch (k)
{
case(1):
{
inBox();
break;
}
case(2):
{
outBox();
break;
}
case(3):
{
find();
break;
}
case(9):
{
ExitProcess;
}
}
}
///end of 菜单
最后是主程序中的调用:
#pragma once
#include"冷库管理.h"
int main()
{
System A;
A.menu();
return 0;
}