1.5.课设实验-数据结构-线性表-手机销售2.0

一.题目:

二.参考代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MaxSize 100 //购物车最多存储数量 

static int PNum; //商品购买数量 
static int PIS; //是否选择该商品

static int i; //循环索引i 

//定义购物车商品结构体
typedef struct
{
	//1.编号
    int BH; 
	//2.品牌(如"Bvlgari")         
    char PP[50];
	//3.型号(如"BHX0023")     
    char XH[50]; 
	//4.产品名称(如"Women Bag")    
    char PName[100];
	//5.产品价格 
    double PPri;
	//6.库存量        
    int PKCNum;  
	//7.促销(例如"300-40"就是满300减40的优惠)    
    char CX[50];     
} PType;

//定义用来存储购物车里的商品的顺序表
typedef struct
{
	//1.用静态数组存放商品,最大容量为MaxSize 
	PType p[MaxSize];
	//2.顺序表当前长度
	int length; 
}SeqList; 

//预定义的产品数据
PType predefinedProducts[] = {
	//编号,品牌,型号,产品名称,产品价格,库存量,促销方案 
    {1, "Bvlgari", "BHX0023", "Women Bag", 112, 100, "0"},
    {2, "Chanel", "CHX0023", "Perfume", 42, 100, "0"},
    {3, "Armani", "AX0023", "Men Watch", 242, 100, "0"},
    {4, "Dior", "DX0023", "Women Watch", 172, 100, "0"},
    {5, "OPPO", "OPPOR30", "OPPOR", 144, 100, "300-40"} 
	};
	
//初始化购物车顺序表
void InitSeqList(SeqList &L) /*形参为购物车*/
{ 
    /* 不需要对静态数组p做NULL赋值,因为它是固定大小的数组
     (L.p=NULL是错误的,因为p是静态数组,不是指针)*/
    
    //1.购物车一开始为空(这一步可以不写)
    for(int i=0; i<MaxSize; i++){
        L.p[i].BH = 0;
        L.p[i].PP[0] = '\0';
        L.p[i].XH[0] = '\0';
        L.p[i].PName[0] = '\0';
        L.p[i].PPri = 0.0;
        L.p[i].PKCNum = 0;
        L.p[i].CX[0] = '\0';
    }
    //2.购物车的长度初始化为0(表示空购物车)
    L.length = 0; 	
} 

// 添加商品到购物车的函数
/*第一个形参为购物车,第二个形参为商品编号*/
bool InsertSeqList(SeqList &L,int addBH)
{
	//1.检查购物车是否已满
	if(L.length >= MaxSize)
	{
		//2.已满 
	    printf("购物车已满,添加失败。 \n");
		return false;	
	} 
	else  
	{
		//3.未满 
		printf("购物车有剩余容量,添加成功。 \n");
		L.p[L.length]=predefinedProducts[addBH-1];
		L.length++; 
		/*对应编号的商品库存量减1*/
		predefinedProducts[addBH-1].PKCNum--; 
		return true;
	}
}

// 解析促销信息,返回满减金额
/*促销的思路就是总金额达到对应商品的满减门槛时,就可以打折*/
int parsePromotion(const char* cx,double totalPri)
{
    //1.如果促销信息为"0",则不进行任何处理
    if (strcmp(cx, "0") == 0)
    {
    	//意味着没有折扣金额 
        return 0;
    }
    //2.此时促销信息不为0,解析"XX-XX"格式的促销信息
    int threshold, discount; //threshold记录满减门槛,discount记录减免金额 
    if (sscanf(cx, "%d-%d", &threshold, &discount) == 2) 
    {
    	/*通过sscanf函数把促销信息cx的满减门槛和减免金额依次赋值给threshold、discount,
		  比如cx为300-40,那么threshold为300,discount为40,现在存了两个数据threshold、discount,sscanf为2*/ 
        //3.如果总金额达到满减门槛threshold,则返回减免金额discount
        if (totalPri >= threshold)
        {
            return discount;
        }
    }
    //4.此时意味着没有达到满减门槛threshold,那么减免金额为0 
    return 0;
}

//计算最终支付总金额的函数
void finalPri(SeqList L)
{
	//1.定义变量记录商品价格总和 
    double totalPri=0;
    //2.求出未处理促销前的总价格
    for(i=0;i<L.length;i++) totalPri=totalPri+L.p[i].PPri;
    printf("未使用促销下总价格为%.2f元 \n",totalPri);
    //3.定义变量 
    /*定义变量记录总共折扣金额*/
    double totalDiscount = 0; 
    /*定义变量记录子促销信息即每一个商品的促销信息*/
    char tempInfo[100];
	/*定义变量记录总促销信息即所有商品的促销信息*/  
    char promotionInfo[100] = "";   
    /*定义变量记录已使用折扣的商品*/
    char appliedProducts[100] = "";
	//4.检查购物车中每个商品的促销信息
    for (i = 0;i<L.length;i++)
    {
    	//4.1.判断当前商品是否有促销,strcmp不为0意味着有促销 
        if (strcmp(L.p[i].CX,"0") != 0)
        {
            //4.2.检查当前商品是否已经应用过折扣
            /*strstr函数用于搜索子字符串,此时用来搜索L.p[i].PName是否存在于appliedProducts里,不存在返回NULL*/
            if (strstr(appliedProducts,L.p[i].PName) == NULL)
            {
            	//4.3.此时意味着还没有使用过折扣,调用parsePromotion函数得出减免金额 
                double discount = parsePromotion(L.p[i].CX, totalPri);
                if (discount > 0)
                {
                	//4.4.此时意味着可以享受折扣,累加所有满足条件的折扣 
                    totalDiscount += discount;
                    //4.5.把当前商品的促销信息整理完整 
                    sprintf(tempInfo, "%s (Spend %d, Save %.2f)", //tempInfo存储促销信息 
                                L.p[i].PName, 
								//第一个%s记录L.p[i].PName即当前可促销商品的名称 
                                atoi(strtok(L.p[i].CX, "-")), 
								/*先利用strtok函数把促销方案CX切割,
								比如促销方案300-40(字符串),这里只调用了一次strtok,且用-切割,
								所以只切割出300,再调用atoi函数把字符串300转为整数,
								最后把300存入第二个%d*/
                                discount
                                //第三个%.2f记录减免金额discount(discount是浮点型,要用%f) 
							);
                    //4.6.将当前促销信息追加到总促销信息字符串
                    strcat(promotionInfo, tempInfo);
                    //4.7.核心:记录已经打过折的商品,将商品名称添加到已应用折扣的列表
                    strcat(appliedProducts, L.p[i].PName);
                    strcat(appliedProducts, "|"); // 使用|作为分隔符
                }
            }
        }
    }
    //5.打印最终支付价格 
	/*如果有促销,打印促销信息和最终金额*/
    if (totalDiscount > 0)
    {
        printf("总促销信息为%s。\n", promotionInfo);
        printf("可享受总共折扣%.2f元,最终需支付%.2f元。\n", totalDiscount,totalPri - totalDiscount);
    }
    else
    /*此时没有促销*/
    {
        printf("没有可享受的促销,最终需支付%.2f元。\n",totalPri); 
    }
} 

// 打印购物车内容
void printShoppingCart(SeqList L)
{
	//1.判断购物车是否为空
	if(L.length==0) 
	{
		printf("购物车为空。\n"); 
		return;
	}
	//2.此时购物车不为空,开始打印购物车信息 
    printf("当前购物车信息如下: \n");
    for(i=0;i<L.length;i++)
    {
    	printf("编号:%d,品牌:%s,型号:%s,产品名称:%s,产品价格:%.2f,库存量:%d \n", 
		L.p[i].BH , L.p[i].PP , L.p[i].XH , L.p[i].PName , L.p[i].PPri , predefinedProducts[L.p[i].BH - 1].PKCNum); //注:库存量在全局变量predefinedProducts里 
	}
	//3.调用finalPri函数得出最终支付价格
	finalPri(L); 
}

//查找指定型号的商品
bool GetXH()
{
	//1.定义变量记录商品型号
	char name[50];  
	//2.开始查找 
	printf("请输入要查找的商品型号:");
	scanf("%s",&name);
	for(i=0;i<5;i++)
	{
		if( strcmp(predefinedProducts[i].XH,name)==0 ) 
		{
			//意味着查找成功
			printf("查找成功 \n"); 
			return true;
		}
	}
	//3.此时查找失败
	printf("查找失败 \n");
	return false; 
} 

//删除购物车商品 
bool SeqListDelete(SeqList &L)
{
	//1.定义变量记录删除哪个商品
	int num; 
	printf("请输入删除第几个商品:");
	scanf("%d",&num);
	//2.判断是否越界
	if(num<1||num>L.length) return false;
	//3.此时没有越界
	for(i=num;i<L.length;i++)
	{
		L.p[num-1]=L.p[num];
		num++; 
	} 
	//4.长度减1
	L.length--;
	//5.返回
	return true; 
}

// 计算最符合300-40的商品
void findPri_300_40(SeqList L)
{
    if (L.length==0)
    {
        //1.此时购物车为空,从商品中找到符合总价值为300的最小值
        printf("此时购物车为空,'满300减40'活动最优商品组合推荐:");
        /*1.1.定义变量记录与目标300最近的差距,初始化为无穷大,因为要找差距更小的*/
        int closestDiff=0X7fffffff; 
        /*1.2.定义变量记录最符合的商品的索引*/
        int bestProductIndex = -1;
        /*1.3.从已有商品中找最接近300的*/
        for (i=0;i<5;i++)
        {
        	//定义变量记录当前商品与300的差距的绝对值 
            int diff = abs(predefinedProducts[i].PPri-300);
            //把当前差距diff与上一次差距closestDiff 
            if (diff < closestDiff)
            {
            	//此时代表当前离300更近,更新最近差距closestDiff,并记录当前商品索引 
                closestDiff = diff;
                bestProductIndex = i;
            }
        }
        if (bestProductIndex != -1)
        {
        	/*此时代表找到了最接近300的商品*/
        	printf("此时最接近300元的商品名称为%s,价格为%.2f元,与300元的差距为%.2f元。 \n",
			        predefinedProducts[bestProductIndex].PName,
					predefinedProducts[bestProductIndex].PPri,
					closestDiff);
        }
        else
        {
            printf("未找到最接近300元的商品.\n");
        }
    }
    else
    {
        //2.此时购物车有商品,基于当前物品找到最优的商品
        printf("此时购物车不为空,寻找适合参加‘满300减40’促销活动的最佳商品 \n");
        /*2.1.定义变量记录当前购物车总金额并计算*/
        double currentTotal;
        for (i=0;i<L.length;i++)
        {
            currentTotal += L.p[i].PPri;
        }
        printf("当前购物车商品总额为%.2f元 \n", currentTotal);
        /*2.2.如果当前购物车总金额超过300,不需要添加商品*/
        if (currentTotal >= 300)
        {
            printf("当前金额已满足满300减40,无需再凑单啦。\n");
        }
        /*2.3.当前购物车总金额未超过300,需寻找使总金额最接近300的商品*/
        //定义变量记录距离300元还差多少 
        int targetDiff = 300 - currentTotal;
        //定义变量记录距离300最近的差值 
        int closestDiff = targetDiff; 
        //定义变量记录距离300最近的商品的索引 
        int bestProductIndex = -1;
        //开始查找符合要求的商品 
        for (i=0;i<5;i++)
        {
            // 检查当前处理的商品是否已在购物车中
            int alreadyInCart = 0;
            for (int j = 0; j < L.length; j++)
            {
                if (predefinedProducts[i].BH == L.p[j].BH)
                {
                	//此时发现购物车存在当前处理的商品,当前处理的商品停止操作,开始处理下一个商品 
                    alreadyInCart = 1;
                    break;
                }
            }
            if (!alreadyInCart)
            {
            	//此时意味着当前处理的商品购物车中没有
				//定义变量记录当前购物车总金额加上当前处理商品的价格 
                int newTotal = currentTotal + predefinedProducts[i].PPri;
                //定义变量记录与300的差 
                int diff = abs(newTotal - 300);
                if (diff < closestDiff)
                {
                	//此时代表有更接近的差值,更新差值并记录当前处理的商品的索引 
                    closestDiff = diff;
                    bestProductIndex = i;
                }
            }
        }
        if (bestProductIndex != -1)
        {
        	//此时代表找到了更接近300的商品 
            printf("找到了‘满300减40’促销活动的最佳商品: \n");
            printf("该商品的名称为: %s \n", predefinedProducts[bestProductIndex].PName);
            printf("该商品的价格为: %.2f元 \n", predefinedProducts[bestProductIndex].PPri);
            printf("此时需支付总金额为: %.2f元 \n", currentTotal + predefinedProducts[bestProductIndex].PPri);
            printf("距离300差: %d元 \n", closestDiff);
        }
        else
        {
            printf("未找到‘满300减40’促销活动的最佳商品。 \n");
        }
    }
}

int main()
{
	//1.定义购物车并初始化 
	SeqList L;
	InitSeqList(L);
	
	//2.购物界面
	printf("=================================欢迎来到您的购物车================================= \n"); 
	
	//3.显示现有商品 
    printf("可选择的商品如下:\n");
    printf("编号,品牌,型号,产品名称,产品价格,库存量,促销方案 \n");
    for (int i = 0; i < 5; i++)
    {
        printf("%d,%s,%s,%s,%.2f,%d,%s \n",
		predefinedProducts[i].BH,     //编号 
		predefinedProducts[i].PP,     //品牌
		predefinedProducts[i].XH,     //型号 
		predefinedProducts[i].PName,  //名称 
		predefinedProducts[i].PPri,   //价格
		predefinedProducts[i].PKCNum, //库存量
		predefinedProducts[i].CX      //促销方案 
		);  
    }
    printf("=================================================================================== \n");
    printf("现在有如下选择: \n");
    printf("1.生成订单及订单明细表   2.添加购物车商品             \n");
    printf("3.删除购物车商品         4.找到价格最接近300-40的商品 \n");
    printf("5.查找指定型号的商品     6.退出购物车                 \n");
    while(true)
    {
    	//开始选择 
    	printf("请输入上述操作的编号:");
    	int choice;
	    scanf("%d",&choice);
		switch(choice)
		{
			case 1: 
			{
				printShoppingCart(L);
				printf("=================================================================================== \n");
				break;
			}
			case 2: 
			{
				printf("请输入要添加的商品数量:");
				scanf("%d",&PNum);
				for(int i=0;i<PNum;i++)
				{
					printf("请输入要添加的商品的编号:");
				    int addBH; //商品编号 
				    scanf("%d",&addBH);
				    //判断是否选择该商品
					printf("是否选择该商品(1.是;2.不是):");
					scanf("%d",&PIS);
					if(PIS==2) continue; 
					else InsertSeqList(L,addBH); 
				}
				printf("=================================================================================== \n");
				break;
			}
			case 3:
			{
				SeqListDelete(L);
				printf("=================================================================================== \n");
				break;
			} 
			break;
			case 4: 
			{
				findPri_300_40(L);
				printf("=================================================================================== \n");
				break; 
			}
			case 5:
			{
			    GetXH();
			    printf("=================================================================================== \n");
				break;	
			}
			case 6: exit(0);
		} 
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值