数据结构大作业——药店模拟

题目

实验背景

你是一家药店的老板,这个月你从供货商手里收到了一批共50个药品, 其中每个药品有独立的进价和保质期,其中进价的区间为[20,30]元,保质期的剩余天数为[1,15]天,你每天可以陈列出10个药品在商店中售卖,每天会有三个顾客各过来购买一个药品。 药品的定价只能为商品进价加上{-1.5,-1, -0.5, 0, 2 ,4 ,6}元,不得随意定价。 每位顾客购买的逻辑是,买其中最便宜的药品,如果说最便宜的药品价格一致则购
买保质期⻓的药品。 三位顾客会依次购买药品。 药品如果没有陈列在商店中,而是存放在仓库时,会收取管理费,其中保质期低于5天的每天收取1元管理费,其余的每天收取0.5元。
药品过期当天丢弃
每天的陈列药品可以少于10个
你的目标是,10天之后,你的利润(售出商品售价总和-售出商品进价总和-支付仓库的管理费用-10天内过期/丢弃商品的进价)最大。

实验要求

能够完整的模拟整个流程,给定药品的进价以及保质期,给定每天陈列的药品,可以直接得到商家的利润;
能够自己制定每天展示的药品策略,给定一定的进价和保质期的药品,能够自己指定策略,得到利润;
代码逻辑清晰,条理清楚;

一、问题描述

  1. 药品具有独立的进价和保质期
    进价的区间为[20,30]元,保质期的剩余天数为[1,15]天
  2. 每天可以陈列出10个药品在商店中售卖
    每天会有三个顾客各过来购买⼀个药品
  3. 定价只能为商品进价加上{-1.5,-1,-0.5,0, 2,4,6}元
  4. 每位顾客购买的逻辑是,买其中最便宜的药品
    最便宜的药品价格⼀致则购买保质期⻓的药品
  5. 药品存放在仓库时,会收取管理费
    保质期低于5天的每天收取1元管理费,其余的每天收取0.5元
  6. 药品过期当天要丢掉
    每天陈列的样品可以少于10个
  7. 利润=售价总和-进价总和-管理费用-10天内过期/丢弃商品的进价
    目标是十天后利润最大

二、实现策略

  1. 模拟方法:
    包含三个类:药品类、药品列表、模拟药店
    药品类中包含药品的ID号、保质期、成本
    药品列表包含一个药品型的数组、药品总数
    函数包含插入药品、删除药品、调整药品状态(上架或存放在仓库)、按价格或保质期排序、药品下架入库等功能
    模拟药店类包含天数、一个药品列表、总利润
    函数有读取文件medicine.txt信息的构造函数、删除过期药品、模拟教辅数据、模拟自己的最有策略等功能
  2. 将药品按保质期排序,保质期小的放在数组前面
    保质期相同的,比较价格,价格高的放在数组前面
    出售时,按排序后的顺序出售,每次售卖三个药品,利润定为6
  3. 将价格高于出售药品的药品摆上货架
  4. 对药品实行预处理,即对于必然会丢弃的药品,在第一天就丢弃,则不用交付管理费
    实现方法:丢弃药品时,加回该药品这几天交的管理费

三、代码实现

(一) 药品类medicine.h的编写

私有成员包含药品ID号、生产日期、成本

private:
    int ID;
    int data;                               //保质期
    double cost;                            //成本

共有函数:初始化、为私有成员提供接口

medicine::medicine(int id=-1, int d=0, double c=0):
    ID(id), data(d), cost(c), state(0)
{}
int medicine::getID(void)
{
    return ID;
}
int medicine::getData(void)
{
    return data;
}
double medicine::getCost(void)
{
    return cost;
}

//删除药品只需把ID改为-1
void medicine::delete_medicine(void)
{
    ID = -1;
}

(二) 药品队列类med_list.h的编写

私有成员包括药品总数和药品数组,最大药品数设为50
#define MaxMedSize 50
定义药品类这个数据结构
typedef medicine DataType;
私有成员:药品总数、药品数组
private:
int amount;
DataType MedList[MaxMedSize];
公共函数:

public:
    med_list(void);                                 //初始化
    void MedInsert(int id, int d, double c);       //药品进货
    DataType findMed(int id);                       //查看药品
    void changeState(int id, int st);               //调整药品状态
    void deleteMed(int id);                         //卖出、丢弃药品
    void sort_MedList_data_cost(void);              //优先按保质期排序,相等时再按价格排序
    void removeMed(void);                           //药品下架入库
    int getAmount(void);
    int getNotSell(void);

构造函数,将药品数量置为0,不卖药品数置为0

med_list::med_list(void) : amount(0), notSell(0)
{}

插入药品函数
当药品数达到50个时,输出已满信息

void med_list::MedInsert(int id, int d, double c)
{
    if(amount == MaxMedSize)
    {
        cout << "药品已满" << endl;
        exit(1);
    }
    medicine tmp(id, d, c);
    MedList[id] = tmp;
    amount++;
}

返回药品,用于下一个文件提取药品

DataType med_list::findMed(int id)
{
    return MedList[id];
}

改变药品状态,上架时置为1,收回仓库置为0

void med_list::changeState(int id, int st)
{
    MedList[id].state = st;
}

删除药品
当药品丢弃或卖出时执行该操作
将该药品id置为-1,药品总数减1

void med_list::deleteMed(int pos)
{
    MedList[pos].delete_medicine();
    amount--;
}

将药品从架子上取回,放回仓库
遍历药品数组,将所有药品的状态置为1

void med_list::removeMed(void)
{
    for(int i=0; i<MaxMedSize; i++)
    {
        if(MedList[i].state == 1)
            MedList[i].state = 0;
    }
}

排序,优先按保质期排序,保质期相等的情况下按价格排序
保质期短、价格昂贵的排在前面
//时间紧的在前面

void med_list::sort_MedList_data_cost(void)
{
    for(int i=0; i<MaxMedSize; i++)
    {
        for(int j=i+1; j<MaxMedSize; j++)
        {
            if(MedList[i].getData() > MedList[j].getData())
            {
                medicine tmp = MedList[i];
                MedList[i] = MedList[j];
                MedList[j] = tmp;
            }
            else if(MedList[i].getData() == MedList[j].getData() && MedList[i].getCost() < MedList[j].getCost())
            {
                medicine tmp = MedList[i];
                MedList[i] = MedList[j];
                MedList[j] = tmp;
            }
        }
    }
}

(三) 实现simulation,模拟给定数据

(med_store.h模拟部分、runsimulation.cpp)
1.
私有成员:天数、总利润、药品列表

private:
    int day;
    double tProfit;
    med_list ml;

共有函数:构造函数、管理费用、删除过期药品、模拟

    med_store(char *filename);
    void GetManagePrice(void);
    void delete_overdue_decision(char *filename);
    void decision(char *filename, char *delname);

构造函数中,将medicine.txt当作参数输入
读取药品参数,生产药品列表

med_store::med_store(char *filename)
{
    day = 0;
    tProfit = 0;
    FILE *fp = fopen(filename, "r");
    for(int i=0; i<MaxMedSize; i++)
    {
        int d;
        double c;
        fscanf(fp, "%lf\t%d\n", &c, &d);
        ml.MedInsert(i, d, c);
    }
    fclose(fp);
}

收取管理费,遍历药品列表,对未删除、状态为在库内的药品收取费用
保质期5天一下利润减1元,5天以上减0.5元

void med_store::GetManagePrice(void)
{
    for(int i=0; i<50; i++)
    {
        if(ml.findMed(i).getData()-day <= 5 && ml.findMed(i).getID() != -1 && ml.findMed(i).state == 0)
            tProfit -= 1;
        else if(ml.findMed(i).getID() != -1 && ml.findMed(i).state == 0)
            tProfit -= 0.5;
    }
}

删除过期药品,读取delete.txt文件
遍历文件中所有要删除的药品,将保质期与天数进行对比
若相等,则删去该药品,并从利润中扣去该药品的进价

void med_store::delete_overdue_decision(char *filename)
{
    FILE *fp = NULL;
    fp = fopen(filename, "r");

    int d;
    int id;
    while(fscanf(fp, "%d\t%d\n", &d, &id)!=EOF)
    {
        if(day == d)
        {
            ml.deleteMed(id);
            tProfit -= ml.findMed(id).getCost();
        }
    }

    fprintf(fp, "\n");
    fclose(fp);
}

模拟数据,读取strategy.txt文件
将strategy.txt和delete.txt作为参数输入
void med_store::decision(char *filename, char *delname)
生产利润索引
double profit_list[7] = {-1.5, -1, -0.5, 0, 2 ,4 ,6};
遍历10天(即10行)

    for(int i=0; i<10; i++)
    {
        day = i;
        double price[10];
        int id_list[10], num = 0;
        for(int j=0; j<10; j++)
            price[j] = 10000;
遍历这一天的10件商品
将每天的药品卖价(=进价+利润)存入price数组
将id号存入id_list数组
将药品状态置为“上架”
        for(int j=0; j<10; j++)
        {
            int id;
            int suoyin;
            fscanf(fp, "%d,%d\t", &id, &suoyin);
            double c = profit_list[suoyin];
            if(id != -1)
            {
                ml.changeState(id, 1);
                price[num] = ml.findMed(id).getCost() + c;
                id_list[num] = id;
                num++;
            }
            fscanf(fp, "\n");
        }
        /*
对这一天的药品卖价进行排序
价格低的放在前面
价格相等时,保质期长的放在前面
price和id_list要同时进行移动操作
*/
        for(int j=0; j<num; j++)
        {
            for(int k=j+1; k<num; k++)
            {
                if(price[j] > price[k])
                {
                    double tmp0 = price[j];
                    price[j] = price[k];
                    price[k] = tmp0;
                    int tmp1 = id_list[j];
                    id_list[j] = id_list[k];
                    id_list[k] = tmp1;
                }
                else if(price[j] == price[k] && ml.findMed(j).getData() > ml.findMed(k).getData())
                {
                    double tmp0 = price[j];
                    price[j] = price[k];
                    price[k] = tmp0;
                    int tmp1 = id_list[j];
                    id_list[j] = id_list[k];
                    id_list[k] = tmp1;
                }
            }
        }
        /*
筛选出当天价格最低的三个药品,最先卖出
删除药品,从总利润中减去药品进价
*/
        for(int j=0; j<3; j++)
        {
            ml.changeState(id_list[j], 1);
            tProfit += price[j] - ml.findMed(id_list[j]).getCost();
            ml.deleteMed(id_list[j]);
        }
//收取管理费、药品下架、清除过期药品
        this->GetManagePrice();
        ml.removeMed();
        this->delete_overdue_decision(delname);

编写runsimulation.cpp文件
传入头地址和三个文件的命名

    char top[] = "D:\\data\\simulation\\data";
    char readfiletail[] = "\\medicine.txt";
    char strategytail[] = "\\strategy.txt";
    char deletetail[] = "\\delete.txt";

循环10次,运行10个data文件

    for (int i = 1; i < 11; i++)
//将文件路径拼接在一起
        char *MedFilename = (char *)malloc(strlen(top) + strlen(number) + strlen(readfiletail));
        char *StrFilename = (char *)malloc(strlen(top) + strlen(number) + strlen(strategytail));
        char *DelFilename = (char *)malloc(strlen(top) + strlen(number) + strlen(deletetail));
//将字符串格式化
        sprintf(MedFilename, "%s%s%s", top, number, readfiletail);
        sprintf(StrFilename, "%s%s%s", top, number, strategytail);
        sprintf(DelFilename, "%s%s%s", top, number, deletetail);
//运行
        med_store ms(MedFilename);
        ms.decision(StrFilename, DelFilename);

(四) 实现自己的策略

(med_store最优策略部分、BestBenefit.cpp)
1.
公有函数:新增策略函数、修改删除药品函数

    med_store(char *filename); 
    void GetManagePrice(void); 
    void delete_overdue(char *filename);
    void strategy(char *filename);
    int get_day(void);
    double get_tProfit(void);
    double get_tCost(void);
    void simulation(char *StrFilename, char *DelFilename);

删除药品函数
如果是第一次打开delete.txt文件,则覆盖原文件内容
从第二次开始,在文件后面更新输入内容
在原删除函数的基础上添加了预处理功能
即将要丢弃的药品在第一天就丢弃,减少管理费用
方法:丢弃时,将收取的管理费加回来
保质期大于5天的加0.5元,小于5天加1元

void med_store::delete_overdue(char *filename)
{
    FILE *fp = NULL;
    if(day == 0)
        fp = fopen(filename, "w");
    else
        fp = fopen(filename, "a+");
    fprintf(fp, "第%d天:", day);

    for(int i=0; i<MaxMedSize; i++)
    {
        if(ml.findMed(i).getData() == day && ml.findMed(i).getID() != -1)
        {
            fprintf(fp, "%d,%lf\t", ml.findMed(i).getID(), ml.findMed(i).getCost());
            ml.deleteMed(i);
            tProfit -= ml.findMed(i).getCost();
            if(day >= 5)
                tProfit += (day-5) * 0.5 + 5 * 1;
            else
                tProfit += day * 1;
        }
    }

    fprintf(fp, "\n");
    fclose(fp);
}

策略函数:将策略写入strategy.txt文件中
void med_store::strategy(char *filename)
先将药品列表按保质期为最高优先级排序
ml.sort_MedList_data_cost();
选择卖出药品
卖出药品列表中的排序前3的药品,利润全部设为6

    int sellNum = 0, i = 0, maxPrice = 0;
    while(sellNum != 3 && i < MaxMedSize)
    {
        if(ml.findMed(i).getID() != -1){
            ml.changeState(ml.findMed(i).getID(), 1); 
            if(maxPrice < ml.findMed(i).getCost())
                maxPrice = ml.findMed(i).getCost();
            tProfit += 6;
            fprintf(fp, "卖出:%d,%.4lf\t", ml.findMed(i).getID(), ml.findMed(i).getCost() + 6);
            ml.deleteMed(i); 
            sellNum++;
        }
        i++;
    }

选择摆上架子但不出售的药品
在列表中选出价格高于出售药品的药品
最多可上架7个
上架的药品状态置为1

    int shangjiaNum = 0, j = 0;
    while(shangjiaNum != 7 && j < MaxMedSize)
    {
        if(ml.findMed(j).getID() != -1 && ml.findMed(j).state != 1 && ml.findMed(j).getCost() > maxPrice)
        {
            ml.changeState(ml.findMed(j).getID(), 1);
            shangjiaNum++;
            fprintf(fp, "上架:%d,%.4lf\t", ml.findMed(j).getID(), ml.findMed(j).getCost() + 6);
        }
        j++;
    }

simulation函数模拟整个策略
天数由0增至9
每天执行卖药上架策略、删除过期药品、收取管理费、药品下架入库、天数自增
循环结束后,输出总利润

    while(day < 10)
    {
        this->strategy(StrFilename);
        this->delete_overdue(DelFilename);
        this->GetManagePrice();
        ml.removeMed();
        day++;
    }
    cout << tProfit << endl;
  • 13
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
好的,药房管理系统是一个常见的应用场景,下面是一份C语言数据结构药房管理系统的课程设计思路,供您参考。 ## 1. 需求分析 药房管理系统主要实现以下功能: 1. 药品信息管理:包括药品名称、规格、价格、库存等信息的维护。 2. 药品进销存管理:包括药品的进货、销售和库存管理。 3. 药品销售管理:包括药品销售记录、销售统计等功能。 ## 2. 设计思路 ### 2.1 数据结构设计 为了实现药房管理系统的功能,需要定义以下数据结构: 1. 药品信息结构体(drug):包括药品名称、规格、价格、库存等信息。 2. 药品进销存结构体(stock):包括药品数量、进货价、销售价等信息。 3. 药品销售记录结构体(sale):包括销售数量、销售时间、销售金额等信息。 使用链表来存储药品信息、药品进销存信息和药品销售记录信息。 ### 2.2 主要功能设计 1. 药品信息管理功能:包括药品信息的添加、删除、修改和查询。将药品信息存储在链表中,可以通过遍历链表来实现查询、删除和修改操作。 2. 药品进销存管理功能:包括药品的进货、销售和库存管理。将药品进销存信息存储在链表中,可以通过遍历链表来实现进货、销售和库存管理。 3. 药品销售管理功能:包括药品销售记录、销售统计等功能。将药品销售记录信息存储在链表中,可以通过遍历链表来实现销售记录和销售统计功能。 ## 3. 编码实现 根据上述设计思路,可以编写C语言代码实现药房管理系统。具体实现过程中需要注意以下问题: 1. 使用链表存储数据时,需要定义节点结构体,包括数据域和指针域。 2. 在链表中插入、删除节点时,需要注意头节点和尾节点的处理。 3. 在查询、修改、删除、遍历链表时,需要注意链表为空的情况。 4. 在处理文件输入输出时,需要注意文件打开、读写、关闭等操作。 ## 4. 总结 药房管理系统的设计和实现需要考虑到实际应用场景和使用要求,合理的数据结构和算法设计可以提高系统的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ETO降临派

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值