药店的药品销售统计系统

实现医药公司定期对销售各药品的记录进行统计,可按药品的编号、单价、销售量或销售额做出排名。

功能要求:

(1)载入:从数据文件中读出各药品的信息记录,存储在顺序表中。各药品的信息包括:药品编号、药名、药品单价、销出数量、销售额。药品编号共 4位,采用字母和数字混合编号,如: A125,前一位为大写字母,后三位为数字

(2)排序:按药品编号进行排序时,可采用基数排序法。对各药品的单价、销售量或销售额进行排序时,可采用多种排序方法,对单价的排序采用冒泡排序法,对销售量的排序采用快速排序法,对销售额的排序采用堆排序法。

(3)输出:将各种排序结果输出显示。

#pragma once
#pragma warning(disable:4996)
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
//定义顺序表的存储结构;
typedef struct {

	char numb[20];		//编号
	char name[20];		//药名
	float price;		//单价
	int amount;			//销售量
	float sumprice;		//销售额
}RedType;
typedef struct {
	RedType r[105];		//r[0]闲置或用作哨兵单元
	int length;			//顺序表表长
}SqList;

//读取文件
int readFile(SqList& L)
{
	int i = 1;
	FILE* file = fopen("medicines.txt", "r");
	if (file == NULL)
	{
		printf("文件为空!\n");
		return 0;
	}
	else {		//通过fscanf输入 (指针,格式符,取地址)
		while (fscanf(file, "%s %s %f %d %f",&L.r[i].numb, &L.r[i].name, 
			&L.r[i].price, &L.r[i].amount, &L.r[i].sumprice) != EOF)
				//一直读到尾部,EOF作为文件结束的标志
		{
			i++;
		}
		L.length = i-1;
	}
	return 0;
}
//载入文件内容print
void load(SqList L)
{
	printf("|药品编号\t|药名\t |药品单价\t|销售数量\t|销售额\t\n");
	for (int i = 1; i <= L.length; i++)
		printf("|%s\t\t|%s\t |%.2f   \t|%d       \t|%.2f  \t\n",
			L.r[i].numb, L.r[i].name, L.r[i].price, L.r[i].amount, L.r[i].sumprice);
	printf("\n\n");
}

//基数排序-- 编号(numb)
void RadixSort(SqList& L)
{
	//int min = 1, max = 1;
	//for (int i = 1; i <= L.length; i++)
	//{
	//	for (int j = 1; j <= L.length; j++)
	//	{
	//		if (strcmp(L.r[min].numb, L.r[j].numb) > 0)
	//			min = j;//找出本次循环最小的
	//		if (strcmp( L.r[j].numb,L.r[max].numb) > 0)
	//			max = j;
	//	}
	//	/*//选择排序
	//	if (min != i)
	//	{
	//		strcpy(L.r[0].numb, L.r[min].numb);
	//		strcpy(L.r[min].numb, L.r[i].numb);
	//		strcpy(L.r[i].numb, L.r[0].numb);
	//	}*/
	//}
	char *temp = (char*)malloc(sizeof(char));
	//*printf("min:%d\n", min);
	//printf("L.r[min].numb:%s\n", L.r[min].numb);
	//printf("max:%d\n", max);
	//printf("L.r[max].numb:%s\n", L.r[max].numb);*/
	RedType bucket[10][10] = { 0 };
	char dest[5] = { 0 };
	int r=0;
	int i, j, k;
	int record[10][10] = { 0 };			//用于记录
	int flag = 0;
	int n = 5;
	for (k = 3; k >= 0; k--)
	{
		for (i = 1; i <= L.length; i++)
		{
			j = 0;
			strncpy(dest, L.r[i].numb + k, 1);	//建字符串数组逐个取出
				/*strcpy() 函数用来复制字符串;strncpy()用来复制字符串的前n个字符,所以要多传一个参数n
				har *strcpy(char *dest, const char *src);
				char * strncpy(char *dest, const char *src, size_t n);
				不像strcpy(),strncpy()不会向dest追加结束标记'\0'*/
			r = atoi(dest);			//将字符串数字变成整型
				/*atoi():int atoi(const char *str );
				功能:把字符串转换成整型数。
				str:要进行转换的字符串
				返回值:每个函数返回 int 值,此值由将输入字符作为数字解析而生成。 
				如果该输入无法转换为该类型的值,则atoi的返回值为 0。
				说明:当第一个字符不能识别为数字时,函数将停止读入输入字符串。*/
			if(r==0)
			{
				if (n == 2)				//取出字母的ASCII的个位
				{
					r = dest[0];
					r %= 10;
				}
				if (n == 1)				//取出字母的ASCII的十位
				{
					r = dest[0];
					r /= 10;
				}
			}
			while (record[r][j] != 0)	//分别按照个、十、百位放进桶里
				j++;
			record[r][j] = 1;
			strcpy(bucket[r][j].numb, L.r[i].numb);
			bucket[r][j] = L.r[i];
		}
		int pos = 0;
		for (i = 0; i < 10; i++)
			for (j = 0; j <= L.length; j++)
				if(record[i][j]==1)		//将bucket里的数字(字符串)依次拿出
				{
					pos++;
					L.r[pos] = bucket[i][j];
					record[i][j] = 0;
					bucket[i][j] = { 0 };
				}
		if (n > 0)		//n为码位
		{
			n--;
			if (n == 1)
				k += 1;
		}
	}
	load(L);
}


//堆排序--销售额(sumprice)
//是选择排序的一种,从逻辑上来理解成顺序存储的二叉树
void HeapAdjust(SqList& L, int k,int length)
{
	 L.r[0]= L.r[k];
	 L.r[0].sumprice = L.r[k].sumprice;
	 //  让i指向当前结点的左孩子
	for (int i = 2 * k; i <=length; i *= 2)					//沿着关键字较大的子节点向下筛选 
	{
		if (i < length && L.r[i].sumprice > L.r[i + 1].sumprice)	//取关键字较大的子节点的下标
			i++;
		if (L.r[i].sumprice >= L.r[0].sumprice)				//筛选结束
			break;
		else {
			L.r[k] = L.r[i];								//将L.r[i]这个较大的调整到双亲节点上
			k = i;											//修改k值,以便继续向下筛选
		}
	}
	L.r[k] = L.r[0];										//被筛选结点的值被放入最终位置
}
void BuildMinHeap(SqList& L,int length)						//建立小根堆
{
	for (int k = length  / 2; k > 0; k--)					//从后往前调整所有非终端的节点
		HeapAdjust(L, k,length);
}
void HeapSort(SqList& L)
{
	int length = L.length;
	BuildMinHeap(L,length);
	for (int i = length; i > 1; i--)
	{
		L.r[0] = L.r[i];
		L.r[i] = L.r[1];
		L.r[1] = L.r[0];
		HeapAdjust(L, 1, i - 1);
	}
	load(L);
}

//冒泡排序---单价(price)
//一次比较两个元素
void BubbleSort(SqList& L)
{
	int i, j;
	for (i = 1; i <= L.length ; i++) // 外层循环控制比较轮数
	{
		for (j = 1; j <= L.length - i; j++)// 内层循环控制每轮的比较次数 
		{
			if (L.r[j].price < L.r[j + 1].price) // 如果前一个元素的价格小于后一个元素的价格
			{
				L.r[0] = L.r[j];
				L.r[j] = L.r[j + 1];// 将后一个元素移到前一个位置
				L.r[j + 1] = L.r[0];
			}
		}
	}
	load(L);
}

//快速排序---销售数量(amount)
int Patition(SqList& L, int low, int high) 
{
	//交换顺序表L中子表r[low..high]的记录,枢轴记录到位,并返回其所在位置
	//此时在它之前(后)的记录均不大于(小于)它
	L.r[0] = L.r[low];                //用子表的第一个记录作枢轴记录
	int pivotkey = L.r[low].amount;      //枢轴记录关键字
	while (low < high) {              //从表的两端向中间扫描
		while (low < high && L.r[high].amount <= pivotkey)
			--high;
		L.r[low] = L.r[high];         //将比枢轴小的记录移动到低端
		while (low < high && L.r[low].amount >= pivotkey)
			++low;
		L.r[high] = L.r[low];         //将比枢轴大的记录移动到高端
	}
	L.r[low] = L.r[0];                //枢轴记录到位
	return low;                       //返回枢轴位置
}
void QSort(SqList& L, int low, int high) 
{
	//对顺序表L中的子序列L.r[low...high]做快速排序
	if (low < high) {                          //长度大于等于1
		int pivotloc = Patition(L, low, high); //一分为二
		QSort(L, low, pivotloc - 1);           //对低子表递归排序
		QSort(L, pivotloc + 1, high);          //对高子表递归排序
	}
}
void QuickSort(SqList& L) 
{
	//对顺序表L做快速排序
	QSort(L, 1, L.length);
	load(L);
}

#include"medicines.h"

//主菜单
void menu()
{
	printf("*************************************\n");
	printf("**** 药店的药品销售统计系统 *********\n");
	printf("*************************************\n");
	printf("****\t1.载入文件内容\t*************\n");
	printf("****\t各种排序:\t\t*****\n");
	printf("****\t2.药品编号--基数排序\t*****\n");
	printf("****\t3.药品单价--冒泡排序\t*****\n");
	printf("****\t4.销售数量--快速排序\t*****\n");
	printf("****\t5.销售额----堆排序\t*****\n");
	printf("****\t0.退出\t\t*************\n");
	printf("******* 请选择 **********************\n");
}

int main()
{
	system("color F0\n");
	menu();
	SqList L;
	readFile(L);
	int n;
	while (1)
	{
		scanf("%d", &n);
		switch (n)
		{
		case 1://输入
			//system("cls");
			//menu();
			printf("载入文件内容\n");
			load(L);
			break;
		case 2://排序
			//system("cls");
			//menu();
			printf("药品编号--基数排序\n");
			printf(" 基数排序\n");
			RadixSort(L);
			break;
		case 3:
			//system("cls");
			//menu();
			printf("药品单价--冒泡排序\n");
			printf("	     	         冒泡排序\n");
			BubbleSort(L);
			break;
		case 4:
			//system("cls");
			//menu();
			//printf("销售数量--快速排序\n");
			printf("					 快速排序\n");
			QuickSort(L);
			break;
		case 5:
			//system("cls");
			//menu();
			printf("							 堆排序\n");
			HeapSort(L);
			//BuildMaxHeap(L);
			break;
		case 0:exit(0);//退出
			break;
		default:printf("无效,请重新输入!!\n");
		}
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值