8.4作业

在这里插入图片描述

#include"goods.h"
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
//创建菜单输出函数
void menue_create(){
	printf("请输入您的需求:\n");
	printf("0.退出系统\n");
	printf("1.继续向表中添加元素\n");
	printf("2.按名字查询该商品的过期时间\n");
	printf("3.将商品所有信息移除(按商品名查询)\n");
	printf("4.商品信息修改\n");
	printf("5.展示已有所有商品信息\n");
	printf("6.在一个商品后插入新商品信息\n");
	printf("7.输出最贵或者最便宜的商品的信息\n");
	printf("8.输入要将所有商品按价格升序排列(1)还是降序排列(0)\n");
}
//创建一个关于要修改内容的菜单
void menue_create_ch(){
	printf("0.取消\n");
	printf("1.修改商品名称\n");
	printf("2.修改商品产地\n");
	printf("3.修改商品的品牌\n");
	printf("4.修改商品价格\n");
	printf("5.修改商品生产日期\n");
	printf("6.修改商品保质期\n");
}
//创建根据flag判断是否展示的函数
void show_or_not(int flag,seqlist_ptr S){
	if(flag){
		listShow(S);
	}
}
//创建顺序表
seqlist_ptr listCreate(){
	//在堆区申请一个顺序表的空间大小
	seqlist_ptr S = (seqlist_ptr)malloc(sizeof(seqlist));
	//判断是否申请成功
	if(NULL == S){
		printf("顺序表创建失败\n");
		return NULL;
	}
 
	//此时顺序表已经创建成功
	memset(S->data,0,sizeof(S->data));  //清空数组
	S->len = 0;  //数组长度清零
 
	printf("顺序表创建成功\n");
	return S;
}
//判满,成功返回真,失败返回假
int listFULL(seqlist_ptr S){
	//判断逻辑
	if(NULL == S){
		printf("所给顺序表不合法\n");
		return 0;
	}
 
	//合法,则返回是否已经满了
	return S->len == MAX;
}
//判空,如果空返回真,非空返回假
int listEmpty(seqlist_ptr S){
	//判断逻辑
	if(NULL == S){
		printf("所给顺序表不合法\n");
		return 0;
	}
 
	//合法返回是否空
	return S->len == 0;
}
//创建顺序表数据元素输入函数
datatype data_input(){
	datatype e;
	printf("请输入商品的名称:");
	scanf("%s",e.name);
	printf("请输入商品的产地:");
	scanf(" %s",e.position);
	printf("请输入商品的品牌:");
	scanf(" %s",e.brand);
	printf("请输入商品的价格:");
	scanf("%lf",&e.price);
	while(1){
		printf("请输入商品的生产日期(年 月 日):");
		scanf("%d%d%d",&e.DOP.year,&e.DOP.month,&e.DOP.day);
		printf("请输入商品的保质期(天):");
		scanf("%d",&e.EXP);
		printf("请输入今天的日期(年 月 日):");
		scanf("%d%d%d",&e.updatas.year,&e.updatas.month,&e.updatas.day);
		if(e.DOP.year<=e.updatas.year&&e.DOP.month>0&& e.DOP.month<=12&&\
				e.DOP.day>0&& e.DOP.day<32&&\
				e.updatas.month>=0&& e.updatas.month<=12&& e.updatas.day>0&&\
				e.updatas.day<32){//只有输入正确才能跳出死循环
			if(e.DOP.year==e.updatas.year){//生产日期的年份如果等于今日,判断月份是否合理
				if(e.DOP.month==e.updatas.month&&e.DOP.day<=e.updatas.day){
					break;
				}
				if(e.DOP.month<e.updatas.month){
					break;
				}
			}else{
				break;
			}
		}
		printf("输入有误,请重新输入\n");
	}
	e.expriation = data_caculate(e.DOP,e.EXP);
	printf("输入成功\n");
	return e;
}
//向顺序表中添加元素
int listAdd(seqlist_ptr S,datatype e){
	//判断逻辑
	if(NULL == S||listFULL(S)){
		printf("添加失败\n");
		return 0;
	}
 
	//添加逻辑
	S->data[S->len] = e;//将新元素放入最后一个位置
 
	//表的变化
	S->len++;
 
	printf("添加成功\n");
	return 1;
}
//遍历顺序表
void listShow(seqlist_ptr S){
	//判断逻辑
	if(NULL == S||listEmpty(S)){
		printf("遍历失败\n");
		return; //会报警告
	}
 
	//遍历顺序表
	printf("当前顺序表的元素分别是:\n");
	int i = 0;
	for(i=0; i<S->len; i++){
		data_output(S->data[i]);
		printf("*********************************************\n");
	}
	putchar(10);
}
//元素输出函数
void data_output(datatype e){
	printf("******************************************\n");
	printf("商品的名称:%s\n",e.name);
	printf("商品的产地:%s\n",e.position);
	printf("商品的品牌:%s\n",e.brand);
	printf("商品的价格:%.2f\n",e.price);
	printf("商品的生产日期:%d年%d月%d日\n",e.DOP.year,e.DOP.month,e.DOP.day);
	printf("商品的保质期(天):%d\n",e.EXP);
	printf("商品信息更新的日期:%d年%d月%d日\n",e.updatas.year,e.updatas.month,e.updatas.day);
	printf("商品过期的日期:%d年%d月%d日\n",e.expriation.year,e.expriation.month,e.expriation.day);
}
//创建日期计算函数
datas data_caculate(datas e,int day){
	int flag = 0;//定义一个标志位,记录润平年
	int i = 0;
	for(i=0; i<day; i++){
		if(e.year%4==0&& e.year%100!=0|| e.year%400==0){
			flag = 1;  //如果是闰年,标志位为1;
		}else{
			flag = 0;  //如果不是,标志位为0;
		}
		e.day += 1;
		switch(e.month){
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
			if(32 == e.day){
				e.day = 1;
				e.month++;
			}//大月有31天,如果天数变成32,说明到了下一个月的1号,月数加1,天数变回1
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			if(31 == e.day){
				e.day = 1;
				e.month++;
			}
			break;
		case 2:
			if(29+flag == e.day){
				e.day = 1;
				e.month++;
			}
			break;
		case 12:
			if(32 == e.day){
				e.day = 1;
				e.month = 1;
				e.year++;
			}
			break;
		}
	}
	return e;
}
 
//任意位置插入元素
int listInsertByPos(seqlist_ptr S,int pos,datatype e){
	//判断逻辑
	if(NULL == S||listFULL(S)||pos<0||pos>S->len){
		printf("插入失败\n");
		return 0; 
	}
 
	//腾空过程
	int i = 0;
	for(i=S->len-1; i>=pos; i--){
		S->data[i+1] = S->data[i]; //将当前元素后移
	}
 
	//插入逻辑
	S->data[pos] = e;  //将新元素放入要插入的位置
 
	//表的变化
	S->len++;
 
	printf("插入成功\n");
	//	listShow(S);
	return 1;
}
 
//任意位置删除元素
int listDeletPos(seqlist_ptr S,int pos){
	//判断逻辑
	if(NULL == S||listEmpty(S)||pos<0||pos>S->len){
		printf("删除失败\n");
		return 0; //会报警告
	}
 
	//删除过程
	int i = 0;
	for(i=pos+1; i<S->len; i++){
		S->data[i-1] = S->data[i]; //将当前元素后移
	}
 
	//表的变化
	S->len--;
 
	printf("删除成功\n");
	//	listShow(S);
	return 1;
}	
#if 0
//按位置进行修改
int listUpdataPos(seqlist_ptr S,int pos, datatype e){
	//判断逻辑
	if(NULL == S||listEmpty(S)||pos<0||pos>S->len){
		printf("修改失败\n");
		return 0;
	}
 
	//更新逻辑
	S->data[pos] = e;
 
	printf("更新成功\n");
	return 1;
}
 
//查找指定位置的元素
datatype *listSearchByPos(seqlist_ptr S,int pos){
	//判断逻辑
	if(NULL == S||listEmpty(S)||pos<0||pos>=S->len){
		printf("查找失败\n");
		return NULL;
	}
 
	//可以进行找到并返回
	return &S->data[pos];
 
}
#endif
//按值进行查找元素返回元素的位置
int listSearchByValue(seqlist_ptr S,datatype e){
	//判断逻辑
	if(NULL == S || listEmpty(S)){
		printf("查找失败\n");
		return -1;
	}
	//遍历顺序表对比是否有与要找的元素相同的元素
	for(int i=0; i<S->len; i++){
		if(!strcmp(e.name,S->data[i].name)){
			return i;   //找到就直接返回下标
		}
	}
 
	/*printf("没有找到\n");*/
	return -1;  //如果整个for循环都执行完了,还没有跳出,说明遍历顺序表也没能找到要找的元素
	//返回-1,表示没找到。
}
#if 0
//按值进行修改
int listUpdataValue(seqlist_ptr S,datatype old_e,datatype new_e){
	//判断逻辑
	if(NULL == S || listEmpty(S) || old_e == new_e){
		printf("修改失败\n");
		return 0;
	}
 
	//可以进行修改,并且全部修改
	int index = 0;
	while((index = listSearchByValue(S,old_e)) >=0 ){
		//调用按位置进行修改函数
		listUpdataPos(S,index,new_e);
	}
 
	printf("修改成功\n");
	return 1;
}
#endif
//将顺序表排序(使用选择排序,传一个flag,1升0降)
void listSort(seqlist_ptr S,int flag){
	//判断逻辑
	if(NULL == S){
		printf("所给顺序表不合法\n");
		return;
	}
	//选择排序
	int i = 0;
	int j = 0;
	int index = 0;//定义记录下标的变量
	datatype tmp;//定义交换的中间变量
	for(i=1; i<S->len; i++){   //控制交换的趟数
		index = 0;
		if(1 == flag){         //如果flag是1,表示升序排列
			for(j=0; j<=S->len-i; j++){  //一直要比到data中的最后一个元素,即下表为len-1的元素,
				//之后每次都可以少比较1个元素,但由于i是从1开始的,所以判断条件为<=len-i
				if(S->data[index].price<S->data[j].price){
					index = j;//如果遍历到的元素比index对应的元素还大,就把更大的值的下标赋给index,以找到最大值的下标
				}
			}
			if(index!=S->len-i){  //将得到的最大值,和最后一个元素交换位置,第二大的和倒数第二个
				//元素交换位置,以此类推
				tmp = S->data[index];
				S->data[index] = S->data[S->len-i];
				S->data[S->len-i] = tmp;
			}
		}else{//降序排列
			for(j=0; j<=S->len-i; j++){  //一直要比到data中的最后一个元素,即下表为len-1的元素,
				//之后每次都可以少比较1个元素,但由于i是从1开始的,所以判断条件为<=len-i
				if(S->data[index].price>S->data[j].price){
					index = j;//如果遍历到的元素比index对应的元素还小,就把更小的值的下标赋给index,以找到最小值的下标
				}
			}
			if(index!=S->len-i){  //将得到的最小值,和最后一个元素交换位置,第二小的和倒数第二个
				//元素交换位置,以此类推
				tmp = S->data[index];
				S->data[index] = S->data[S->len-i];
				S->data[S->len-i] = tmp;
			}			
		}
	}
}
#if 0
//将顺序表去重
void listUnique(seqlist_ptr S){
	//判断逻辑
	if(NULL == S || S->len <= 1){
		printf("进入失败\n");
		return;
	}
	//去重逻辑
	int i = 0;
	int j = 0;
	for(i=0; i<S->len; i++){
		//将当前元素后面的所有元素遍历一遍
		for(j=i+1; j<S->len; j++){
			if(S->data[i] == S->data[j]){
				//删除j这个元素
				listDeletPos(S,j);
				j--;   //防止漏删
			}
		}
	}
	printf("去重成功\n");
}
#endif
//求最值操作
int listMoValue(seqlist_ptr S,int flag){
/*	//判断逻辑
	if(NULL == S){
		printf("所给顺序表不合法\n");
		return 0;
	}	
	*/
	//求最值
	int pos = 0;
	double value = S->data[0].price; //定义一个变量保存最值
	int i = 0;
	for(i=0; i<S->len; i++){
		if(1 == flag){   //如果flag为1说明要求最大值,否则为最小值
			if(value< S->data[i].price){
				value = S->data[i].price;
				pos = i;
			}
		}else{
			if(value> S->data[i].price){
				value = S->data[i].price;
				pos = i;
			}		
		}
	}
	return pos;
}
//最值元素输出
void most_output(seqlist_ptr S,int flag){
	//判断逻辑
	if(NULL == S|| S->len==0){
		printf("最值查找失败\n");
		return ;
	}
	if(1 == flag){
		printf("最贵的商品信息为:\n");
	}else{
		printf("最便宜的商品信息为:\n");
	}
	int pos = 0;
	pos = listMoValue(S,flag);
	int i = 0;
	for(i=0; i<S->len; i++){
		if(S->data[i].price==S->data[pos].price){
			data_output(S->data[i]);
		}
		
	}
	
}
#if 0
//顺序表反转
void listReverse(seqlist_ptr S){
	//判断逻辑
	if(NULL == S){
		printf("所给顺序表不合法\n");
		return;
	}
	int i = 0;
	datatype tmp = 0;//定义一个中间变量
	for(i=0; i<S->len/2; i++){    //交换次数为len/2次,比如,有4个元素,那么len正好等于4,交换2次,3个元素交换1次,3/2也是1
		tmp = S->data[i];
		S->data[i] = S->data[S->len-1-i];
		S->data[S->len-1-i] = tmp;
	}
}
#endif
//顺序表释放
void listFree(seqlist_ptr S){
	if(NULL != S){
		free(S);
		S = NULL;
	}
}

#ifndef _GOODS_H_
#define _GOODS_H_
#define MAX 40 				//定义顺序表的最大容量
typedef struct
{
	int year;
	int month;
	int day;
}datas;//存储年月日
typedef struct 
{
	char name[32]; //存储商品名称
	char position[32];  //存储商品产地
	char brand[32];  //存储商品的品牌
	double price;  //存储商品价格
	datas DOP;  //存储商品的生产日期
	int EXP;  //存储商品的保质期
	datas updatas;  //存储商品信息更新日期
	datas expriation; //存储商品过期时间
}datatype;  //以整形为例,数据元素类型
//定义顺序表类型的基本格式
typedef struct
{
	datatype data[MAX];    //存储数据元素的数组
	int len;             //存储当前顺序表的长度
}seqlist,*seqlist_ptr;   //重命名为一个结构体变量,和一个指针类型
//创建菜单输出函数  行5
void menue_create();
//创建一个关于要修改内容的菜单
void menue_create_ch();
//创建根据flag判断是否展示的函数  行15
void show_or_not(int flag,seqlist_ptr S);
//创建顺序表  行21
seqlist_ptr listCreate();
//判断空  行49
int listEmpty(seqlist_ptr S);
//判断满  行38
int listFULL(seqlist_ptr S);
//创建顺序表数据元素输入函数
datatype data_input();
//创建日期计算函数
datas data_caculate(datas e,int day);
//向顺序表中添加元素
int listAdd(seqlist_ptr S,datatype e);
//遍历顺序表
void listShow(seqlist_ptr S);
//元素输出函数
void data_output(datatype e);
//任意位置插入元素
int listInsertByPos(seqlist_ptr S,int pos,datatype e);
//任意位置删除元素
int listDeletPos(seqlist_ptr S,int pos);
//按位置进行修改
int listUpdataPos(seqlist_ptr S,int pos, datatype e);
//按值进行修改
int listUpdataValue(seqlist_ptr S,datatype old_e,datatype new_e);
//查找指定位置的元素
datatype *listSearchByPos(seqlist_ptr S,int pos);
//按值进行查找元素返回元素的位置
int listSearchByValue(seqlist_ptr S,datatype e);
//将顺序表排序(使用选择排序,传一个flag,1升0降)
void listSort(seqlist_ptr S,int flag);
//将顺序表去重
void listUnique(seqlist_ptr S);
//求最值操作
int listMoValue(seqlist_ptr S,int flag);
//最值元素输出
void most_output(seqlist_ptr S,int flag);
//顺序表反转
void listReverse(seqlist_ptr S);
//顺序表释放
void listFree(seqlist_ptr S);
#endif

#include"goods.h"
#include<stdio.h>
int main(int argc, const char *argv[])
{
	seqlist_ptr S = listCreate();//调用顺序表调用函数
	if(NULL == S){
		printf("顺序表创建失败\n");
		return 0;
	}	//只有顺序表创建成功才能进入后续步骤
	int choice = 0;
	datatype e;
	int pos;
	int flag = 0;
	while(1){
		menue_create();
		scanf("%d",&choice);
		switch(choice){
		case 0:
			goto LOOP;
			break;
		case 1:
			printf("请输入要添加的元素内容:\n");
			e = data_input();//调用输入函数,获取数据
			flag=listAdd(S,e);//调用添加元素函数
			//show_or_not(flag,S);//根据上一步的返回值决定要不要输出
			break;
		case 2:
			printf("请输入要查询的商品名:");
			scanf("%s",e.name);
			pos = listSearchByValue(S,e);//根据商品名获取商品信息的位置
			if(-1==pos){
				printf("不存在该商品\n");
				continue;
			}else{
				printf("其过期日期为:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
			}
			break;
		case 3:
			printf("请输入要删除的商品名:");
			scanf("%s",e.name);
			pos = listSearchByValue(S,e);//根据商品名获取其信息在顺序表中的位置
			if(-1==pos){
				printf("商品本就不存在\n");
				continue;
			}else{
				flag=listDeletPos(S,pos);//调用按位置删除函数
				printf("删除成功\n");
				//show_or_not(flag,S);	//根据函数返回值决定是否输出结果			
			}
			break;
		case 4:
			printf("请输入要修改的商品名:");
			scanf("%s",e.name);
			pos = listSearchByValue(S,e);//获取商品信息信息在顺序表中位置
			printf("请输入今天的日期(年 月 日):");
			scanf("%d%d%d",&e.updatas.year,&e.updatas.month,&e.updatas.day);
			printf("请输入要修改的内容:\n");
			menue_create_ch();
			int choice4;
			scanf("%d",&choice4);
			switch(choice4){
			case 0:
				printf("并未进行修改\n");
				break;
			case 1:
				printf("修改前商品的名字为:%s\n",S->data[pos].name);
				printf("请输入修改后的商品名字:");
				scanf("%s",S->data[pos].name);
				printf("修改后商品的名字为:%s\n",S->data[pos].name);
				break;
			case 2:
				printf("修改前商品的产地为:%s\n",S->data[pos].position);
				printf("请输入修改后的商品产地:");
				scanf("%s",S->data[pos].name);
				printf("修改后商品的产地为:%s\n",S->data[pos].position);
				break;
			case 3:
				printf("修改前商品的品牌为:%s\n",S->data[pos].brand);
				printf("请输入修改后的商品品牌:");
				scanf("%s",S->data[pos].brand);
				printf("修改后商品的品牌为:%s\n",S->data[pos].brand);
				break;
			case 4:
				printf("修改前商品的价格为:%.2f\n",S->data[pos].price);
				printf("请输入修改后的商品价格:");
				scanf("%lf",&S->data[pos].price);
				printf("修改后商品的价格为:%.2f\n",S->data[pos].price);
				break;
			case 5:
				printf("修改前商品的生产日期:%d年%d月%d日\n",S->data[pos].DOP.year,S->data[pos].DOP.month,S->data[pos].DOP.day);
				printf("修改前商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
				while(1){
					printf("要将商品的生产日期(年 月 日)改为:");
					scanf("%d%d%d",&e.DOP.year,&e.DOP.month,&e.DOP.day);
					if(S->data[pos].DOP.year<=S->data[pos].updatas.year&&S->data[pos].DOP.month>0&& S->data[pos].DOP.month<=12&&\
							S->data[pos].DOP.day>0&& S->data[pos].DOP.day<32&&\
							S->data[pos].updatas.month>=0&& S->data[pos].updatas.month<=12&& S->data[pos].updatas.day>0&&\
							S->data[pos].updatas.day<32){//只有输入正确才能跳出死循环
						if(S->data[pos].DOP.year==S->data[pos].updatas.year){//生产日期的年份如果等于今日,判断月份是否合理
							if(S->data[pos].DOP.month==S->data[pos].updatas.month&&S->data[pos].DOP.day<=S->data[pos].updatas.day){
								break;
							}
							if(S->data[pos].DOP.month<S->data[pos].updatas.month){
								break;
							}
						}else{
							break;
						}
					}
					printf("输入有误,请重新输入\n");	
				}
				e.expriation = data_caculate(S->data[pos].DOP,S->data[pos].EXP);
				printf("输入成功\n");				
				printf("修改后商品的生产日期:%d年%d月%d日\n",S->data[pos].DOP.year,S->data[pos].DOP.month,S->data[pos].DOP.day);
				printf("修改后商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
				break;
			case 6:
				printf("修改前商品的保质期(天):%d\n",S->data[pos].EXP);
				printf("修改后商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
				printf("请输入要将商品的保质期修改为(天):");
				scanf("%d",&S->data[pos].EXP);
				e.expriation = data_caculate(S->data[pos].DOP,S->data[pos].EXP);
				printf("修改后商品的保质期(天):%d\n",S->data[pos].EXP);
				printf("修改后商品过期的日期:%d年%d月%d日\n",S->data[pos].expriation.year,S->data[pos].expriation.month,S->data[pos].expriation.day);
				break;
			default:
				printf("输入不规范,亲人两行泪,请重新输入\n");
				break;
			}
			printf("修改后该商品的信息为\n");
			data_output(S->data[pos]);
			break;
		case 5:
			listShow(S);
			break;
		case 6:
			printf("请输入想要在那个商品后插入新商品:\n");
			scanf("%s",e.name);
			pos = listSearchByValue(S,e);//根据商品名获取其信息在顺序表中的位置
			if(-1==pos){
				printf("商品不存在\n");
				continue;
			}else{
				printf("请输入要插入的商品信息:\n");
				e = data_input();
				flag=listInsertByPos(S,pos,e);//调用按位置删除函数
				printf("插入成功\n");
				//show_or_not(flag,S);	//根据函数返回值决定是否输出结果			
			}
			break;
		case 7:
			while(1){
				printf("请输入要找最贵的还是最便宜的(1求最贵,0求便宜):");
				scanf("%d",&flag);
				if(1==flag||0==flag){
					break;
				}
				printf("输入不规范,亲人两行泪,请重新输入\n");
			}
			most_output(S,flag);
			break;
		case 8:
			while(1){
				printf("请输入升序排列的还是降序排列的(1升,0奖):");
				scanf("%d",&flag);
				if(1==flag||0==flag){
					break;
				}
				printf("输入不规范,亲人两行泪,请重新输入\n");
			}
			listSort(S,flag);
			break;
		default:
			printf("输入不规范,亲人两行泪,请重新输入\n");
			break;
		}
	}
LOOP:
	printf("感谢使用,再见\n");
	listFree(S);//释放空间
	S = NULL;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值