课设-药店的药品销售统计系统(排序应用)

药店的药品销售统计系统(排序应用)

1.问题描述

[题目描述]

你在一个L药品店当一名仓库管理员,马上就要放寒假回家过年了,L药店对这一年的销售情况做了统计,但这看起来太杂乱无章了。因此,你需要对这些数据进行整理,使他们看起来并不那么糟糕。“哦,我的天,是谁把阿莫新林放在了这?它应该放在那边的!最好在移动前先洗洗手,这样会显得更庄重些”。

所以说,你需要将它们进行排序,这样就会看起来好看。但是,L店长是个冷漠的人,他一语“从小到大”,便拂袖而去,并没有说要对什么属性进行排序。(啧,真麻烦!)这意味着你要分别按照各个属性进行从小到大排序,这些属性分别为“药品编号”(num),“药品名称”(name),“药品单价”(price),“药品销售数量”(count),“药品销售额”(sale=price*count)。

 [输入]

第一行输入一个整数n(3<=n<=100),接下来有n行,每行有四个数据项:字符串num(strlen(num)=4),字符串name(strlen(name)<10),实数price(1<=price<=5e2),整数count(1<=count<=5e3),分别代表药品编号,药品名称,药品单价,药品销售数量。

保证所有数据不相同。换句话来说,无论使用哪种排序方法,保证排序结果唯一。

 [输出]

分别输出药品编号、药品名称、药品单价、药品销售数量、药品销售额按照给定的标准从小到大的排序结果。每个排序结果后跟随一个回车。

[提示]

为了不丢失精度,建议本题所有实数型变量用double定义。

字符串的排序参照其字典序大小。

五种属性排序使用不同的排序算法。

 [样例输入]

4

A001 Valium 3.5 23

A002 Aspirin 9.8 59

A003 Analgin 27.5 37

A004 Insulin 94.8 19

 [样例输出]

A001   Valium 3.5 23  80.5

A002   Aspirin    9.8 59  578.2

A003   Analgin    27.5   37  1017.5

A004   Insulin    94.8   19  1801.2

 

A003   Analgin    27.5   37  1017.5

A002   Aspirin    9.8 59  578.2

A004   Insulin    94.8   19  1801.2

A001   Valium 3.5 23  80.5

 

A001   Valium 3.5 23  80.5

A002   Aspirin    9.8 59  578.2

A003   Analgin    27.5   37  1017.5

A004   Insulin    94.8   19  1801.2

 

A004   Insulin    94.8   19  1801.2

A001   Valium 3.5 23  80.5

A003   Analgin    27.5   37  1017.5

A002   Aspirin    9.8 59  578.2

 

A001   Valium 3.5 23  80.5

A002   Aspirin    9.8 59  578.2

A003   Analgin    27.5   37  1017.5

A004   Insulin    94.8   19  1801.2

[提示]

    为了不丢失精度,建议本题所有实数型变量用double定义。

    字符串的排序参照其字典序大小。

    五种属性排序使用不同的排序算法。

输出格式参考:

    printf("%s\t%s\t%.1lf\t%d\t%.1lf\n", l.r[i].num, l.r[i].name, l.r[i].price, l.r[i].count, l.r[i].sale);

2.需求分析

可以采用顺序表的存储结构,如可定义如下的存储结构:

typedef struct{

    char ID[100];//编号

    char name[100];//名字

    double price;//单价

    int count;//数量

    double total;//总价

}Medicine;

typedef struct{

    Medicine elem[N];

    int length;

}SqList;

3.算法设计

1. CreatList(SqList &ST) //创建顺序表

2. total(SqList &ST) //计算总价

3. show(SqList &ST)//按格式打印输出

4. idpaixu(SqList &ST) //直接插入排序

5. namepaixu(SqList &ST) //冒泡排序

6. pricepaixu(SqList &ST) //折半插入排序

7. countpaixu(SqList &ST) //选择排序

8. Partition(SqList &ST,int low,int high)//一趟快排序

9. QSort ( SqList  &ST,  int low, int high ) //对顺序表L中的子序列r[ low…high] 作快速排序

10. totalpaixu(SqList &ST) //快速排序

4.调试分析

本题采用了冒泡排序、选择排序、直接插入排序、折半排序和快速排序。冒泡排序的优点是:比较简单,空间复杂度较低,是稳定的;缺点是:时间复杂度太高,效率不好。选择排序的优点是:一轮只需要换依次位置;缺点是:效率慢,不稳定。直接插入排序的优点是:稳定,快;缺点是:比较次数不一定,插入点后的数据移动多。折半排序的优点是:稳定,比较次数较少;缺点是:移动次数较多。快速排序的优点是:时间按复杂度低,性能快。缺点是:不稳定。

5.实验结果

#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
typedef char ElemType;
#define N 101
//可以采用顺序表的存储结构,如可定义如下的存储结构: 
typedef struct{
	char ID[100];//编号 
	char name[100];//名字 
	double price;//单价 
	int count;//数量 
	double total;//总价 
}Medicine; 
typedef struct{
	Medicine elem[N]; 
	int length;
}SqList;
void CreatList(SqList &ST) //创建顺序表 
{
	cin >> ST.length;
	for (int i = 0; i<ST.length; i++)
	{
		cin>>ST.elem[i].ID>>ST.elem[i].name>>ST.elem[i].price>>ST.elem[i].count;
	}
}
void total(SqList &ST) //计算总价 
{
	for (int i = 0; i<ST.length; i++)
		ST.elem[i].total = ST.elem[i].price * ST.elem[i].count;
}
void show(SqList &ST)//按格式打印输出 
{
	for (int i = 0; i<ST.length; i++)
        //printf("%-8s%-8s%-8.1lf%-8d%-8.1lf\n",ST.elem[i].ID,ST.elem[i].name,ST.elem[i].price,ST.elem[i].count,ST.elem[i].total);
        printf("%s\t%s\t%.1lf\t%d\t%.1lf\n",ST.elem[i].ID,ST.elem[i].name,ST.elem[i].price,ST.elem[i].count,ST.elem[i].total);
}
void idpaixu(SqList &ST)
{//直接插入排序 
	int i,j; 
    for ( i=2; i<=ST.length; ++i ) 
        if (ST.elem[i].ID < ST.elem[i-1].ID)
	    {   
            ST.elem[0] = ST.elem[i];            // 复制为监视哨
        	ST.elem[i]=ST.elem[i-1];    //ST.elem[i-1]后移 
			for ( j=i-2; ST.elem[0].ID < ST.elem[j].ID;  -- j )
                ST.elem[j+1] = ST.elem[j];        // 记录后移
 		    ST.elem[j+1] = ST.elem[0] ;        // 插入到正确位置  
        }
   show(ST);
}

void namepaixu(SqList &ST)
{//冒泡排序 
	Medicine L; 
	for(int i=0;i<ST.length;i++)
	{
	    for(int j=i;j>=1;j--)
		{
		    if(strcmp(ST.elem[j-1].name,ST.elem[j].name)>0)
		    {
		    	L=ST.elem[j];
				ST.elem[j]=ST.elem[j-1];
				ST.elem[j-1]=L;
			}
		}
	}
   show(ST);
}
void pricepaixu(SqList &ST)
{//折半插入排序 
	int i,j,m,high,low;
	Medicine L;
	for ( i=1; i<ST.length; ++i ) {
        L = ST.elem[i];      // 将 ST.elem[i] 暂存到 L
		low = 0;   high = i-1;
		while (low<=high) { 
		    m = (low+high)/2; 
			if (L.price<ST.elem[m].price)
        	    high = m-1;   // 插入点在低半区
			else  low = m+1; // 插入点在高半区
        }
		for ( j=i-1;  j>=high+1;  --j )
    	    ST.elem[j+1] = ST.elem[j];      // 记录后移
		ST.elem[high+1] = L;  // 插入(位置)
    } // for
   show(ST);
}
void countpaixu(SqList &ST)
{//选择排序 
	Medicine L; 
	for(int i=0;i<ST.length;++i)
	{
	    int k=i;
	    for(int j=i+1;j<ST.length;++j)
		{
		    if(ST.elem[j].count<ST.elem[k].count) k=j;
			if(k!=i)
			{
			    L=ST.elem[i];
				ST.elem[i]=ST.elem[k];
				ST.elem[k]=L;
			}
		}
	}
   show(ST);
}

int Partition(SqList &ST,int low,int high){ //一趟快排序
//交换子表 ST.elem[low…high]的记录,使支点(枢轴)记录到位,并返回其位置。
//返回时,在支点之前的记录均不大于它,支点之后的记录均不小于它。 
    Medicine L;
	L=ST.elem[low];  //以子表的首记录作为支点记录,放入ST.elem[0]单元
	int pivotkey=ST.elem[low].total;  //取支点的关键码存入pivotkey变量
    while(low < high){ 	//从表的两端交替地向中间扫描
        while(low<high && ST.elem[high].total>=pivotkey ) -- high;
    	ST.elem[low]=ST.elem[high];  //将比支点小的记录交换到低端;
    	while(low<high && ST.elem[low].total<=pivotkey)  ++low;
  		ST.elem[high]=ST.elem[low];   //将比支点大的记录交换到高端;
    }
    ST.elem[low]=L;     //支点记录到位
   return low;    //返回支点记录所在位置。
}//Partition

void QSort ( SqList  &ST,  int low, int high ) 
{//对顺序表L中的子序列ST.elem[ low…high] 作快速排序
    if ( low < high) {	//长度>1			  
       int pivot = Partition ( ST, low, high ); //一趟快排,将ST.elem[ ]一分为二
       QSort ( ST, low, pivot-1);	    //在左子区间进行递归快排,直到长度为1
       QSort ( ST, pivot+1, high );//在右子区间进行递归快排,直到长度为1
    }
}
void totalpaixu(SqList &ST)
{//快速排序 
	QSort (ST,  0,  ST.length-1 );
   show(ST);
}
int main()
{
	SqList ST;
	CreatList(ST);
	total(ST);
	idpaixu(ST);
	cout<<endl;
	namepaixu(ST);
	cout<<endl;
	pricepaixu(ST);
	cout<<endl;
	countpaixu(ST);
	cout<<endl;
	totalpaixu(ST);
	return 0;
}

 

  • 9
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值