[问题描述]

使用双向链表模拟快递驿站的系统运作:

+ 假设快递驿站的货架分小、中、大3种类型,容量分别为500、100、50个包裹;该快递站关联的社区人员为MAX_PERSON人(例如,限定为30人,每人唯一手机号)。

+ 驿站每天都会来一批新的包裹。包裹根据大小类型分别上对应的货架,加入对应链表表尾,并使用该货架当前可用的最小编号。用N[1]、N[2]、N[3]分别表示每天随机来的大、中、小包裹数量,保证N[i]在货架的承受能力之内。

+ 包裹信息包括:包裹编号(生成的取件码,分别为1-x(小),2-x(中), 3-x(大))、取件人姓名、取件人手机号、包裹大小(小1、中2、大3)、到达日期。

+ 包裹上架时,按照包裹编号从小到大的顺序排列。

+ 包裹取出后就从对应链表中删除。用M表示每天随机来取包裹的人数,且M≤MAX_PERSON。

+ 包裹最多在驿站存放两天,逾期则退还寄件人(从货架上清除)。

+ 当一人来取包裹时,可通过提供其任一取件码或手机号查询包裹并取出该人员所有关联的包裹。

+ 设计相应的分析、统计功能(自定义),例如当天收包裹数量最多的人,当天有包裹人的平均包裹数量,一周内与其被退回的包裹数量等。

+ 可根据需要做功能拓展,使得模拟系统更接近实用或在现有商用快递系统的基础上有针对性的创新(*)

+ 该问题需有较好的展示性,能够演示快递收发过程。

[基本要求]

  1. 所有事件均随机生成

  1. 用文件存储货架状态,所有变更均应反应在文件中。存储形式自行设计,但务必清晰、直观

解题思考:

(1)把日期封装成类,便于处理。包裹保存为结构体。创建一个全局变量Vis[4][505]来保存货架上的位置情况。但要创建一个保存取件人姓名、手机号的文件。另外,包裹分为三个状态:0:未取件;1:已取件;2:已退件。

(2)每次运行程序时,第一步从Package.dat文件中读取原有数据,构建3个双向链表(不论原文件中有没有数据,都要构建)。

(3)添加新到的包裹,编号不是随机生成的,而是使用对应货架当前可用的最小编号。快递生成编号时,与Vis[4][505]进行比较来查重。然后依据编号大小进行插入操作。

(4)根据每个包裹的日期执行退还操作,即在文件中将其删除(将这一步放到第2步一起执行,读取Package.dat文件中的数据时顺便检查是否有未领取包裹的时间超过了两天)。

(5)因为一开始就确定了来取包裹的人数,所以不适合一个人一个人的进行取包裹操作,于是我将取包裹变成了随机事件,放在一起处理。取包裹时,用取件码或手机查询这个人的所有包裹,并将其取出。对于取走的包裹,改变它的状态为已领取,再修改文件。

(6)最后就是关于统计了,当天收到包裹数量最多的人可以放到第3步一起做,可以创建一个全局变量People[30](这里假定为30人),添加新包裹的同时,给对应的收件人加1;当天有包裹人的平均包裹数量,这个根据已有的People[30]也容易处理;一周内被退回的包裹数量,我们的Package.dat文件保存有一周内的包裹信息,直接打开文件统计状态为“退回”的包裹的数量就可以了。

注:数据积累一周,在周一的时候再清理已取或退还的快递的信息。这样可以方便进行一周的统计,以及导出任意人员的收件情况。另外,我增加“查询任意人员过去三天的取件记录”的功能。

Date.h的代码(用于时间处理的头文件):

# include <windows.h>
# include <iostream>using namespace std;class Date                               //表示日期的类
{private:int year;//年 int month;//月 int day;  //日void simplify(); //调整日期(--) public:Date(int y = 0, int m = 0, int d = 0){year = y;month = m;day = d;}void SetToday();//完成对Date型的当前日期赋值 Date operator =(const Date& right);//重载"=",以完成对Date型的直接赋值bool operator ==(const Date& right);//重载"==",以完成Date型的比较bool operator >(const Date& right); //重载">",以完成Date型的比较bool operator <(const Date& right); //重载"<",以完成Date型的比较        int operator -(const Date& right); //重载"-",以求出任意两天的间隔天数int Week();     //求今天是星期几Date operator --();   //重载前置--  friend istream& operator >>(istream&, Date&); //重载">>",完成Date型的直接输入friend ostream& operator <<(ostream&, Date&); //重载"<<",完成Date型的直接输出
};void Date::simplify()
{int y = year, m = month, d = day;int p = 0;if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){p = 1;}if (p)   //如果是闰年 {switch (m){case 1:if (d < 1) { y--; m = 12; d = 31; } break;case 2:if (d < 1) { m--; d = 31; } break;case 3:if (d < 1) { m--; d = 29; } break;case 4:if (d < 1) { m--; d = 31; } break;case 5:if (d < 1) { m--; d = 30; } break;case 6:if (d < 1) { m--; d = 31; } break;case 7:if (d < 1) { m--; d = 30; } break;case 8:if (d < 1) { m--; d = 31; } break;case 9:if (d < 1) { m--; d = 31; } break;case 10:if (d < 1) { m--; d = 30; } break;case 11:if (d < 1) { m--; d = 31; } break;case 12:if (d < 1) { m--; d = 30; } break;}}else{switch (m){case 1:if (d < 1) { y--; m = 12; d = 31; } break;case 2:if (d < 1) { m--; d = 31; } break;case 3:if (d < 1) { m--; d = 28; } break;case 4:if (d < 1) { m--; d = 31; } break;case 5:if (d < 1) { m--; d = 30; } break;case 6:if (d < 1) { m--; d = 31; } break;case 7:if (d < 1) { m--; d = 30; } break;case 8:if (d < 1) { m--; d = 31; } break;case 9:if (d < 1) { m--; d = 31; } break;case 10:if (d < 1) { m--; d = 30; } break;case 11:if (d < 1) { m--; d = 31; } break;case 12:if (d < 1) { m--; d = 30; } break;}}
}istream& operator >>(istream& strm, Date& obj)//重载">>",完成Date型的直接输入
{cout << "\t\t*年*:";strm >> obj.year;cout << "\t\t*月*:";strm >> obj.month;cout << "\t\t*日*:";strm >> obj.day;return strm;
}void Date::SetToday()//显示今日日期,并完成对Date型的赋值
{int y, m, d;SYSTEMTIME sys;GetLocalTime(&sys);year = sys.wYear;month = sys.wMonth;day = sys.wDay;
}ostream& operator <<(ostream& strm, Date& obj) //重载"<<",完成Date型的直接输出
{strm << obj.year << "年" << obj.month << "月" << obj.day << "日";return strm;
}Date Date::operator =(const Date& right)//重载"=",完成日期的直接赋值
{year = right.year;month = right.month;day = right.day;return *this;
}Date Date::operator --()   //重载前置--
{--day;simplify();return *this;
}bool Date::operator ==(const Date& right)//重载"==",以完成Date型的比较
{if (year == right.year && month == right.month && day == right.day){return true;}else{return false;}
}bool Date::operator >(const Date& right) //重载">",以完成Date型的比较
{if (year > right.year){return true;}else if (year == right.year && month > right.month){return true;}else if (year == right.year && month == right.month && day > right.day){return true;}else{return false;}
}bool Date::operator <(const Date& right)   //重载"<",以完成Date型的比较
{if (year < right.year){return true;}else if (year == right.year && month < right.month){return true;}else if (year == right.year && month == right.month && day < right.day){return true;}else{return false;}
}int Date::operator -(const Date& right) //重载"-",以求出任意两天的间隔天数
{int y1 = year, m1 = month, d1 = day;//大天数 int y2 = right.year, m2 = right.month, d2 = right.day;//小天数 int p1 = 0, p2 = 0; //判断是否为闰年int a1 = 0, a2 = 0; //判断这一天是这一年的第几天 int a3 = 0; //间隔天数 if ((y1 % 4 == 0 && y1 % 100 != 0) || y1 % 400 == 0){p1 = 1;}if ((y2 % 4 == 0 && y2 % 100 != 0) || y2 % 400 == 0){p2 = 1;}if (p1){switch (m1){case 1: a1 += d1; break;case 2: a1 += 31 + d1; break;case 3: a1 += 60 + d1; break;case 4: a1 += 91 + d1; break;case 5: a1 += 121 + d1; break;case 6: a1 += 152 + d1; break;case 7: a1 += 182 + d1; break;case 8: a1 += 213 + d1; break;case 9: a1 += 244 + d1; break;case 10: a1 += 274 + d1; break;case 11: a1 += 305 + d1; break;case 12: a1 += 335 + d1; break;}}else{switch (m1){case 1: a1 += d1; break;case 2: a1 += 31 + d1; break;case 3: a1 += 59 + d1; break;case 4: a1 += 90 + d1; break;case 5: a1 += 120 + d1; break;case 6: a1 += 151 + d1; break;case 7: a1 += 181 + d1; break;case 8: a1 += 212 + d1; break;case 9: a1 += 243 + d1; break;case 10: a1 += 273 + d1; break;case 11: a1 += 304 + d1; break;case 12: a1 += 334 + d1; break;}}if (p2){switch (m2){case 1: a2 += d2; break;case 2: a2 += 31 + d2; break;case 3: a2 += 60 + d2; break;case 4: a2 += 91 + d2; break;case 5: a2 += 121 + d2; break;case 6: a2 += 152 + d2; break;case 7: a2 += 182 + d2; break;case 8: a2 += 213 + d2; break;case 9: a2 += 244 + d2; break;case 10: a2 += 274 + d2; break;case 11: a2 += 305 + d2; break;case 12: a2 += 335 + d2; break;}}else{switch (m2){case 1: a2 += d2; break;case 2: a2 += 31 + d2; break;case 3: a2 += 59 + d2; break;case 4: a2 += 90 + d2; break;case 5: a2 += 120 + d2; break;case 6: a2 += 151 + d2; break;case 7: a2 += 181 + d2; break;case 8: a2 += 212 + d2; break;case 9: a2 += 243 + d2; break;case 10: a2 += 273 + d2; break;case 11: a2 += 304 + d2; break;case 12: a2 += 334 + d2; break;}}if (y1 == y2){a3 = a1 - a2;}else{for (int i = y2 + 1; i < y1; i++){if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0){a3 += 366;}else{a3 += 365;}}if (p2 == 1){a3 = a3 + a1 + 366 - a2;}else{a3 = a3 + a1 + 365 - a2;}}return a3;
}int Date::Week()     //求今天是星期几
{ Date d1(2022, 11, 20);     //2022.11.20是周日Date d2(year, month, day);int a = d2 - d1;int b = a % 7;if (b == 0) {b = 7;}return b;
}

主程序代码:

# include <iostream>
# include <stdlib.h>
# include <fstream>
# include <string.h>
# include <stdlib.h>
# include <windows.h>
# include <iomanip>
# include <random>
# include <time.h>
# include "Date.h"
# define maxp 30    //人员总数
# define maxn 505
# define maxn1 500  //货架1的最大容量
# define maxn2 100  //货架2的最大容量
# define maxn3 50   //货架3的最大容量
# define maxp1 10   //每天新到的小包裹的最大数目
# define maxp2 5    //每天新到的中包裹的最大数目
# define maxp3 3    //每天新到的大包裹的最大数目
# define maxp4 10   //每天来取包裹的最大人数using namespace std;typedef struct Package
{int condition;   //包裹的收取状态(0.待收;1.已收;2.退还)int size;        //包裹大小int num;         //在货架上的位置编号int code;        //取件码char name[15];   //取件人姓名char phone[12];  //取件人手机号Date day;        //到达日期struct Package* prev;   //前驱结点struct Package* next;   //后继结点
}Package;void frame();                          //框架函数
void Outline();                       //界面菜单
void Create();                          //从文件中读取数据,创建三个货柜的双向链表
void SetPackage(int i, int n, int m); //设置添加单个包裹
void Insert(Package p);                  //根据包裹大小和编号插入指定货架的相应位置
void AddPackages();                      //添加今日新到的包裹
void Delete(Package p);                  //从货架的双向链表中删除包裹
void TakePackages();                  //取走包裹
void Count();                         //统计一些基本情况
void Find();                          //查询人员过去三天的取件记录
void Print(Package* S, int n);        //打印双向链表里的数据
void Show();                          //展现目前三个货架上的快递
void Clear();                         //清理Package.dat文件中的数据
int Vis[4][maxn] = { {0} };              //保存编号(与货柜的位置相对应),查重包裹编号
int People[maxp + 1] = { 0 };          //索引当天每个人收到的快递数
Package* Shelve[4];                      //三个货架
int N[4] = { 0,maxn1,maxn2,maxn3 };   //保存三个货架的剩余容量
Date today;                           //今日日期
int total;                            //每次货架上的包裹总数int main()
{Outline();today.SetToday();cout << "今日日期:" << today << endl;int week = today.Week(); //获取今天是星期几if (week == 1)  //如果是周一,要执行清理Package.dat文件的操作{cout << "\n今日是周一,已自动对包裹数据进行清理" << endl;Clear();}char c;cout << "\n今日退还的包裹:" << endl;cout << "\n输入任意键继续运行:";cin >> c;Create();frame();cout << "\n今日收件前各货架上的包裹状况:" << endl;cout << "\n输入任意键继续运行:";cin >> c;Show();frame();cout << endl;frame();cout << "\n今日新增包裹:" << endl;cout << "\n输入任意键继续运行:";cin >> c;AddPackages();frame();cout << endl;frame();cout << "\n今日收件后各货架上的包裹状况:" << endl;cout << "\n输入任意键继续运行:";cin >> c;Show();frame();cout << endl;frame();cout << "\n今日被取走的包裹:" << endl;cout << "\n输入任意键继续运行:";cin >> c;TakePackages();frame();cout << endl;frame();cout << "\n今日取件后各货架上的包裹状况:" << endl;cout << "\n输入任意键继续运行:";cin >> c;Show();frame();cout << endl;cout << "统计信息:" << endl;Count();frame();cout << "\n查询客户信息" << endl;int select = 1;while (select == 1){Find();cout << "是否继续查询:(1)是 (2)否" << endl;cout << "请选择:";cin >> select;}return 0;
}//框架函数
void frame()
{for (int i = 0; i < 120; i++){cout << "*";}cout << endl;
}//界面菜单
void Outline()
{frame();cout << "\n------------------------------------------------- ";cout << "欢迎进入菜鸟智慧系统";cout << " ----------------------------------------------- \n";frame();cout << '\n';
}//根据包裹大小和编号插入指定货架的相应位置
void Insert(Package p)                //根据包裹大小和编号插入指定货架的相应位置
{Package* pk;pk = (Package*)malloc(sizeof(Package)); //创建指针型的变量,并用包裹数据为其赋值pk->condition = p.condition;pk->size = p.size;pk->num = p.num;pk->code = p.code;strcpy(pk->name, p.name);strcpy(pk->phone, p.phone);pk->day = p.day;int n = pk->size;Package* pN = Shelve[n];while (pN->next != NULL){if (pN->next->num > pk->num)  //寻找该包裹在货架上的位置{break;}pN = pN->next;}pk->next = pN->next;pN->next = pk;pk->prev = pN;if (pk->next != NULL) {pk->next->prev = pk;}
}//从文件中读取数据,创建三个货柜的双向链表
void Create()
{cout.setf(ios::left);Shelve[1] = (Package*)malloc(sizeof(Package));Shelve[2] = (Package*)malloc(sizeof(Package));Shelve[3] = (Package*)malloc(sizeof(Package));Shelve[1]->prev = NULL;Shelve[1]->next = NULL;Shelve[2]->prev = NULL;Shelve[2]->next = NULL;Shelve[3]->prev = NULL;Shelve[3]->next = NULL;Package p;fstream file1, file2;file1.open("Package.dat", ios::in | ios::binary); //二进制读取文件中已有的包裹数据file2.open("Empty.dat", ios::out | ios::binary);  //只写打开空白文件(辅助进行文件修改)if (file2.fail()){cout << "Empty.dat文件打开失败" << endl;exit(0);}int t = 0;if (!file1.fail()){//文件打开失败说明是第一次使用系统,不存在先前数据//文件打开成功说明存在先前数据file1.read((char*)&p, sizeof(p));while (!file1.eof()){if (today - p.day > 2 && p.condition != 2) //检测到包裹存放时间已超过两天{p.condition = 2;         //调整包裹为退还状态cout << "取件码:" << p.code << "\t";cout << "取件人姓名:" << setw(10) << p.name;cout << "取件人手机号:" << p.phone << "\t";cout << "收件日期:" << p.day << "\n";N[p.size]++;Vis[p.size][p.num] = 0;  //将货架的相应位置还原为0t = 1;                   //改变了文件内容,之后需修改文件}else if (p.condition == 0)   //将仍未被收取的包裹放到货架上{Insert(p);Vis[p.size][p.num] = 1;  //将货架的相应位置标注为1N[p.size]--;}file2.write((char*)&p, sizeof(p));file1.read((char*)&p, sizeof(p));}}file1.close();file2.close();if (t) //修改Package.dat{file1.open("Package.dat", ios::out | ios::binary); //只写覆盖打开Package.datfile2.open("Empty.dat", ios::in | ios::binary);    //只读打开空白文件if (file1.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}if (file2.fail()){cout << "Empty.dat文件打开失败" << endl;exit(0);}file2.read((char*)&p, sizeof(p));while (!file2.eof()){file1.write((char*)&p, sizeof(p));file2.read((char*)&p, sizeof(p));}file1.close();file2.close();}else{cout << "无" << endl;}
}//设置添加单个包裹
void SetPackage(int i, int n, int m)
{cout.setf(ios::left);Package p;char str[100], strn[20], strp[15];fstream file, file1;for (int j = 1; j <= n; j++){if (Vis[i][j] == 0)  //寻找货架当前可用的最小位置编号{int x = 10 * i;while (x <= j){x *= 10;}p.code = x + j;  //生成新到包裹的编号p.num = j;       //生成新到包裹的位置编号Vis[i][j] = 1;   //将货架的相应位置标注为1break;}}p.condition = 0;p.size = i;p.day = today;People[m]++;file.open("收件人信息.txt", ios::in);if (file.fail()){cout << "收件人信息.txt文件打开失败" << endl;exit(0);}for (int k = 1; k <= m && !file.eof(); k++){file.getline(str, 100);}int t = 0, ln = 0, lp = 0;for (int k = 0; k < strlen(str); k++)  //处理文本文件,获取随机选中的收件人的姓名和手机号{if (!t){if (str[k] == ' '){t = 1;strn[ln] = '\0';}else{strn[ln] = str[k];ln++;}}else{strp[lp] = str[k];lp++;}}strp[lp] = '\0';strcpy(p.name, strn);strcpy(p.phone, strp);Insert(p);cout << "取件码:" << p.code << "\t";cout << "取件人姓名:" << setw(10) << p.name;cout << "取件人手机号:" << p.phone << "\t";cout << "收件日期:" << today << "\n";file1.open("Package.dat", ios::out | ios::app | ios::binary); //只写追加打开Package.datif (file1.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}file1.write((char*)&p, sizeof(p));file.close();file1.close();
}//添加今日新到的包裹
void AddPackages()
{int m;srand((unsigned int)time(0)); //修改种子int n1 = rand() % maxp1 + 1;  //随机生成新到的小包裹数while (n1 > N[1])  //限定新到的包裹数小于货架剩余的空间{n1 = rand() % maxp1 + 1;}cout << "\n今日新增小包裹" << n1 << "件" << endl;for (int i = 1; i <= n1; i++){m = rand() % maxp + 1;  //随机选中收件人SetPackage(1, maxn1, m);}N[1] -= n1;cout << endl;int n2 = rand() % maxp2 + 1;  //随机生成新到的中包裹数while (n2 > N[2])  //限定新到的包裹数小于货架剩余的空间{n2 = rand() % maxp2 + 1;}cout << "今日新增中包裹" << n2 << "件" << endl;for (int i = 1; i <= n2; i++){m = rand() % maxp + 1;  //随机选中收件人SetPackage(2, maxn2, m);}N[2] -= n2;cout << endl;int n3 = rand() % maxp3 + 1;  //随机生成新到的大包裹数while (n3 > N[3])  //限定新到的包裹数小于货架剩余的空间{n3 = rand() % maxp3 + 1;}cout << "今日新增大包裹" << n3 << "件" << endl;for (int i = 1; i <= n3; i++){m = rand() % maxp + 1;  //随机选中收件人SetPackage(3, maxn3, m);}N[3] -= n3;
}//从货架的双向链表中删除包裹
void Delete(Package p)
{int n = p.size;Package* pN = Shelve[n]->next;while (pN != NULL){if (strcmp(pN->phone, p.phone) == 0)  //寻找该人的所有包裹{pN->prev->next = pN->next;if (pN->next != NULL){pN->next->prev = pN->prev;}}pN = pN->next;}
}//取包裹
void TakePackages()
{int sum = 0;fstream file, file1, file2;Package p;char str[100], strn[20], strp[15];srand((unsigned int)time(0));    //修改种子int n = rand() % maxp4 + 1;      //随机生成来取包裹的人数for (int i = 1; i <= n; i++){int n1 = rand() % maxp + 1;  //随机生成来取包裹的人file.open("收件人信息.txt", ios::in);if (file.fail()){cout << "收件人信息.txt文件打开失败" << endl;exit(0);}for (int k = 1; k <= n1 && !file.eof(); k++){file.getline(str, 100);}int t = 0, ln = 0, lp = 0;for (int k = 0; k < strlen(str); k++)  //处理文本文件,获取随机选中的收件人的姓名和手机号{if (!t){if (str[k] == ' '){t = 1;strn[ln] = '\0';}else{strn[ln] = str[k];ln++;}}else{strp[lp] = str[k];lp++;}}strp[lp] = '\0';file1.open("Package.dat", ios::in | ios::binary); //二进制读取文件中的包裹数据if (file1.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}file2.open("Empty.dat", ios::out | ios::binary);  //只写打开空白文件(辅助进行文件修改)if (file2.fail()){cout << "Empty.dat文件打开失败" << endl;exit(0);}int t1 = 0;int n2 = rand() % 2 + 1;   //随机生成查寻并取走所有包裹的方式if (n2 == 1)               //直接用手机号查询{file1.read((char*)&p, sizeof(p));while (!file1.eof()){if (strcmp(p.phone, strp) == 0 && p.condition == 0) //检测到该人未取的包裹{p.condition = 1;         //调整包裹为已取状态Vis[p.size][p.num] = 0;  //将货架的相应位置还原为0N[p.size]++;Delete(p);cout << "取件码:" << p.code << "\t";cout << "取件人姓名:" << setw(10) << p.name;cout << "取件人手机号:" << p.phone << "\t";cout << "取件日期:" << today << "\n";sum++;t1 = 1;                   //改变了文件内容,之后需修改文件}file2.write((char*)&p, sizeof(p));file1.read((char*)&p, sizeof(p));}}else   //用取件码查询{int s = 0;char str1[15];file1.read((char*)&p, sizeof(p));while (!file1.eof()){if (!s && strcmp(p.name, strn) == 0 && p.condition == 0) //找到一个该人未取的包裹{strcpy(str1, p.phone);  //记下手机号s = 1;}if (s && strcmp(p.phone, str1) == 0 && p.condition == 0){p.condition = 1;         //调整包裹为已取状态Vis[p.size][p.num] = 0;  //将货架的相应位置还原为0N[p.size]++;Delete(p);cout << "取件码:" << p.code << "\t";cout << "取件人姓名:" << p.name << "\t";cout << "取件人手机号:" << p.phone << "\t";cout << "取件日期:" << today << "\n";sum++;t1 = 1;                  //改变了文件内容,之后需修改文件}file2.write((char*)&p, sizeof(p));file1.read((char*)&p, sizeof(p));}}file1.close();file2.close();if (t1)      //修改Package.dat{file1.open("Package.dat", ios::out | ios::binary); //只写覆盖打开Package.datfile2.open("Empty.dat", ios::in | ios::binary);    //只读打开空白文件if (file1.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}if (file2.fail()){cout << "Empty.dat文件打开失败" << endl;exit(0);}file2.read((char*)&p, sizeof(p));while (!file2.eof()){file1.write((char*)&p, sizeof(p));file2.read((char*)&p, sizeof(p));}file1.close();file2.close();}file.close();file1.close();file2.close();}cout << "今日被取走的包裹数:" << sum << endl;
}//统计一些基本情况
void Count()
{fstream file, file1;Package p;char str[100], strn[20];int n = 1;    //保存今天收件最多的人float sum = 0;  //统计今天的收件数int man = 0;  //统计今天的收件人数  for (int i = 1; i <= maxp; i++){sum += People[i];if (People[i] > 0){man++;}if (People[i] > People[n]){n = i;}}file.open("收件人信息.txt", ios::in);if (file.fail()){cout << "收件人信息.txt文件打开失败" << endl;exit(0);}for (int k = 1; k <= n && !file.eof(); k++){file.getline(str, 100);}int ln = 0;for (int k = 0; str[k] != ' '; k++)  //处理文本文件,获取当天收件最多的人的姓名{strn[ln] = str[k];ln++;}strn[ln] = '\0';float aver = sum / man;cout << "当天收包裹数量最多的人为" << strn << " 共" << People[n] << "件" << endl;cout << "当天共收到包裹" << sum << "件" << endl;cout << "当天有包裹人的平均包裹数量为" << setprecision(2) << aver << endl;file1.open("Package.dat", ios::in | ios::binary); //只读打开Package.datif (file1.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}int total = 0;  //统计一周内被退还的包裹数while (!file1.eof()){file1.read((char*)&p, sizeof(p));if (today - p.day < 7 && p.condition == 2){total++;}}cout << "一周内被退回的包裹数量为" << total << endl;file.close();file1.close();
}//查询人员过去三天的取件记录
void Find()
{fstream file;Package p;char s[20];cout << "\n请输入要查询的人员姓名:";cin >> s;file.open("Package.dat", ios::in | ios::binary); //只读打开Package.datif (file.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}cout << endl;cout << s << "最近三天的收件记录:" << endl;int t = 0;while (!file.eof()){file.read((char*)&p, sizeof(p));if (strcmp(p.name, s) == 0 && p.condition == 1 && today - p.day <= 3){t = 1;cout << p.day << "签收了编号为" << p.code << "的包裹" << endl;}}if (!t){cout << s << "最近三天没有收件" << endl;}cout << endl;file.close();
}//打印双向链表里的数据
void Print(Package* S, int n)
{cout.setf(ios::left);Package* p;p = S->next;if (p == NULL) {cout << "货架" << n << "为空" << endl;}else {while (p != NULL) {cout << "取件码:" << p->code << "\t";cout << "取件人姓名:" << setw(10) << p->name;cout << "取件人手机号:" << p->phone << "\t";cout << "到达日期:" << p->day << "\n";total++;p = p->next;}}
}//展现目前三个货架上的快递
void Show()
{total = 0;cout << "\n货架1:" << endl;Print(Shelve[1], 1);cout << "\n货架2:" << endl;Print(Shelve[2], 2);cout << "\n货架3:" << endl;Print(Shelve[3], 3);cout << "\n共有" << total << "件包裹" << endl;
}//清理Package.dat文件中的数据
void Clear()
{fstream file1, file2;Package p;file1.open("Package.dat", ios::in | ios::binary); //只读打开Package.datfile2.open("Empty.dat", ios::out | ios::binary);  //只写覆盖打开空白文件if (file1.fail()){//文件打开失败,说明没有可清理的数据file1.close();file2.close();return;}if (file2.fail()){cout << "Empty.dat文件打开失败" << endl;exit(0);}file1.read((char*)&p, sizeof(p));while (!file1.eof()){if (today - p.day <= 7){file2.write((char*)&p, sizeof(p));}file1.read((char*)&p, sizeof(p));}file1.close();file2.close();file1.open("Package.dat", ios::out | ios::binary); //只写覆盖打开Package.datfile2.open("Empty.dat", ios::in | ios::binary);    //只读打开空白文件if (file1.fail()){cout << "Package.dat文件打开失败" << endl;exit(0);}if (file2.fail()){cout << "Empty.dat文件打开失败" << endl;exit(0);}file2.read((char*)&p, sizeof(p));while (!file2.eof()){file1.write((char*)&p, sizeof(p));file2.read((char*)&p, sizeof(p));}file1.close();file2.close();
}

以上便是我对这道题的看法,很高兴与大家分享。

菜鸟智慧系统(线性表)相关推荐

  1. 菜鸟积分系统稳定性建设 - 分库分表百亿级数据迁移

    点击上方"服务端思维",选择"设为星标" 回复"669"获取独家整理的精选资料集 回复"加群"加入全国服务端高端社群「后 ...

  2. 系统掌握数据结构3线性表C++实现

    线性表 1.逻辑结构 2.存储结构 2.1顺序存储 2.2链式存储 3.线性表的实现 3.1 顺序存储结构实现 3.2顺序存储操作实现 3.3链式存储结构实现(单链表) 3.4链式存储操作实现(单链表 ...

  3. 大话数据结构读书笔记系列(三)线性表

    2019独角兽企业重金招聘Python工程师标准>>> 3.1 开场白 各位同学,大家好.今天我们要开始学习数据结构中最常用和最简单的一种结构,在介绍它之前先讲个例子. 我经常下午去 ...

  4. c语言线性表写的数据库系统(数据结构)

    数据库系统 用C语言的链表知识做了一个简单的数据库,原理简单,可以直接复制代码使用,请大佬指导 #include"consts.h" #include<sys\stat.h& ...

  5. 数据结构—线性表(第三章)—基本知识点总结

    目录 1. 线性表的定义 2. 线性表的抽象数据类型 3.线性表的顺序存储结构 3.1 顺序存储定义 3.2 顺序存储方式 3.3 数据长度与线性表长度区别 3.4 地址计算方法 4. 顺序存储结构的 ...

  6. 线性表-链式存储结构

    3.6 线性表的链式存储结构 3.6.1 顺序存储结构不足的解决办法 前面我们讲的线性表的顺序存储结构.它是有缺点的,最大的缺点就是插入和删除时需要移动大量元素,这显然就需要耗费时间.能不能想办法解决 ...

  7. 数据结构和算法:(3)3.2线性表的链式存储结构

    线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素也就是说你这个可以放在A地点,这个可以放在E地点,A地点和E地点中间可以隔开一个C地点和D地点,这样是允许的),这组存储单元可以存在 ...

  8. 链表list(链式存储结构实现)_5 线性表的链式存储结构

    系列文章参考资料为<大话数据结构>,源码为个人私有,未经允许不得转载 线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,可以使连续的,也可以不连续,也就意味这些元素可以 ...

  9. 【数据结构】 线性表的顺序表

    线性表是一种最为常用的数据结构,包括了一个数据的集合以及集合中各个数据之间的顺序关系.线性表从数据结构的分类上来说是一种顺序结构.在Python中的tuple,list等类型都属于线性表的一种. 从抽 ...

最新文章

  1. 一个比较牛的Js写的五子棋
  2. Vivado生成bitstream报错,DRC NSTD-1与DRC UCIO-1]
  3. 《C和指针》——数组的存储顺序
  4. AWS机器学习初探(1):Comprehend - 自然语言处理服务
  5. JFrame小练习1
  6. C语言如何动态分配空间:malloc
  7. Android Fragment 真正的完全解析(上) (转载)
  8. 移动应用开发 Android Studio安装教程
  9. 简单版数独计算器-升级版
  10. Android系统启动之BOOT_COMPLETED广播
  11. 网络攻防--网络防御技术(一)
  12. Mac技巧之更改苹果电脑开机画面的技巧
  13. 小技巧(10):使用Python绘制激活函数(Sigmoid、Tanh、ReLU、PReLU)图像
  14. Linux基础——makefile编写
  15. Oracle EBS Interface/API(35) -创建供应商地点API
  16. 中冠百年|投资理财,千万不要犯这些错误
  17. (附源码)springboot掌上博客系统 毕业设计 063131
  18. 【趣味实践】自动化抠图工具——XMem的使用
  19. Java手机通讯录并实现自动发送QQ消息及单人视频聊天窗口
  20. 科研小白成长记31——顶会到此一游

热门文章

  1. O-LinuxShell-W6正则表达式相关练习
  2. 压力大吗?AI能测出大学生目前的压力程度
  3. STM32的烧录和Hex/bin烧录文件解析、烧录文件是被如何存储到MCU中的?
  4. grub命令磁盘管理
  5. 嵌入式Qt程序启动参数-qws 不需要X11桌面系统
  6. 简单了解三次握手原理
  7. Rootkit---进程隐藏
  8. 你真的了解眼里所见的色彩吗?(一文总结RGB/HSV/Lab)
  9. java线程池参数_java线程池参数设置原则,如何设置线程池参数比较合理?
  10. homebrew安装及使用nginx