5、药店的药品销售统计系统(排序应用)
[问题描述]
设计一系统,实现医药公司定期对销售各药品的记录进行统计,可按药品的编号、单价、销售量或销售额做出排名。
[实现提示]
在本设计中,首先从数据文件中读出各药品的信息记录,存储在顺序表中。各药品的信息包括:药品编号、药名、药品单价、销出数量、销售额。药品编号共4位,采用字母和数字混合编号,如:A125,前一位为大写字母,后三位为数字,按药品编号进行排序时,可采用基数排序法。对各药品的单价、销售量或销售额进行排序时,可采用多种排序方法,如直接插入排序、冒泡排序、快速排序,直接选择排序等方法。在本设计中,对单价的排序采用冒泡排序法,对销售量的排序采用快速排序法,对销售额的排序采用堆排序法。
药品信息的元素类型定义:
typedef structnode
{ charnum[4]; /*药品编号*/
char name[10]; /*药品名称*/
float price; /*药品单价*/
int count; /*销售数量*/
float sale; /*本药品销售额*/
}DataType;
存储药品信息的顺序表的定义:
typedef struct
{ DataTyper[MaxSize];
int length;
}SequenList;
一、算法设计
1.本次程序一共需要采用4种排序方法,其中感觉最麻烦的就是桶排序(基数排序)和堆排序了。采用桶排序的时候一共开出来26个队列,0~9算是10个。字母的话可以通过减去ASCⅡ码来实现。例如’A’-’A’就变成了整形当中的0,一直到’Z’-’A’。堆排序中采用的是构造大顶堆。这样,每次还换完成之后,把最大值当道最后一个位置。整个排序做完,那么就是按照从小到大的顺序排列的了。对于文件的导入和存储采用的是ifstream和ofstream,txt文档来保存,简化程序。
各个函数的调用关系如下图所示:
|
main() |
|
|||||||||
|
mainjiemian() kaobei() line() |
|
|||||||||
|
read() |
write() |
math_sort() |
en_queue() init_queue() empty_queue() de_queue() |
bubble_sort() |
heap_sort() |
Swap () |
quick_sort() |
partion() |
jieshu() |
|
|
display() |
display() |
shift() |
display() |
|
||||||
|
display() |
|
|||||||||
|
mainjiemian() |
|
|||||||||
2.本程序中包含16个模块
(1)主函数:intmain();
(2)基数排序:math_sort(Sequnenlist* l);
(3)从队列中取出:Datatypede_queue(Linkqueue * q);
(4)药品进队:voiden_queue(Linkqueue * q, Datatype x);
(5)判断队列是否为空:boolempty_queue(Linkqueue * q);
(6)初始化队列:voidinit_queue(Linkqueue * q);
(7)快速排序:voidquick_sort(Sequnenlist * l, int low, int high);
int partion(Sequnenlist * l, int low, int high);
void Swap(Sequnenlist * l, int i, int j);
(8)冒泡排序:voidbubble_sort(Sequnenlist * l);
(9)堆排序:voidheap_sort(Sequnenlist * l);
void shift(Sequnenlist * l, inti, int m);
(10)拷贝数据:copy(Sequnenlist* l, int i, int j);
(11)结束界面:voidjieshu();
(12)主界面:voidmainjiemian();
(13)药品信息导出到文件:voidwrite();
(14)从文件到耻辱药品信息:voidread();
(15)统计共有多少药品:intline();
(16)拷贝文件:voidkaobei();
3.元素类型、结点类型和指针类型
#defineMAXSIZE 10005
intN = 0;
typedefstruct node /*药品信息的元素定义*/
{
string num; /*药品编号*/
string name; /*药品名称*/
float price; /*药品单价*/
float count; /*销售数量*/
float sale; /*本药品销售额*/
}Datatype;
typedefstruct /*存储药品信息的顺序表的定义*/
{
Datatype r[MAXSIZE + 1];
int length;
}Sequnenlist;
Sequnenlist*l = new Sequnenlist;
/*--------------------------------------------------------*/
typedefstruct Linknode/*桶的存储结构*/
{
Datatype data;
struct Linknode * next;
}Lnode;
typedefstruct linkqueue
{
Lnode * front = NULL;/*队头指针*/
Lnode * rear = NULL; /*队尾指针*/
}Linkqueue;
二、实验测试
源代码:
#pragma warning(disable:4996)
#include<stdio.h>
#include<cstdio>
#include<string>
#include<string.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<stack>
#include<math.h>
#include<iomanip>
#include<stdlib.h>
#include<iostream>
#include<list>
#include<fstream>
#include<ostream>
using namespace std;
#define MAXSIZE 10005
int N = 0;
typedef struct node /*药品信息的元素定义*/
{
string num; /*药品编号*/
string name; /*药品名称*/
float price; /*药品单价*/
float count; /*销售数量*/
float sale; /*本药品销售额*/
}Datatype;
typedef struct /*存储药品信息的顺序表的定义*/
{
Datatype r[MAXSIZE + 1];
int length;
}Sequnenlist;
Sequnenlist *l = new Sequnenlist;
/*--------------------------------------------------------*/
typedef struct Linknode/*便道的存储结构*/
{
Datatype data;
struct Linknode * next;
}Lnode;
typedef struct linkqueue
{
Lnode * front = NULL;/*队头指针*/
Lnode * rear = NULL; /*队尾指针*/
}Linkqueue;
/*--------------------------------------------------------*/
void display(Sequnenlist * l) /*显示药品信息*/
{
cout << "序号 " << "编号 " << "名称 " << "单价 " << "销售数量 " << "销售额" << endl;
for (int i = 1; i <= N; i++)
{
cout << "[" << i << "] ";
cout << std::left << setw(8) << l->r[i].num;
cout << std::left << setw(10) << l->r[i].name;
cout << std::left << setw(8) << l->r[i].price;
cout << std::left << setw(13) << l->r[i].count;
cout << std::left << setw(10) << l->r[i].sale << endl;
}
}
/*---------------------------------------------------------*/
void Swap(Sequnenlist * l, int i, int j) /*快速排序,冒泡排序调用函数*/
{
l->r[MAXSIZE + 1].count = l->r[i].count;
l->r[MAXSIZE + 1].name = l->r[i].name;
l->r[MAXSIZE + 1].num = l->r[i].num;
l->r[MAXSIZE + 1].price = l->r[i].price;
l->r[MAXSIZE + 1].sale = l->r[i].sale;
l->r[i].count = l->r[j].count;
l->r[i].name = l->r[j].name;
l->r[i].num = l->r[j].num;
l->r[i].price = l->r[j].price;
l->r[i].sale = l->r[j].sale;
l->r[j].count = l->r[MAXSIZE + 1].count;
l->r[j].name = l->r[MAXSIZE + 1].name;
l->r[j].num = l->r[MAXSIZE + 1].num;
l->r[j].price = l->r[MAXSIZE + 1].price;
l->r[j].sale = l->r[MAXSIZE + 1].sale;
}
/*----------------------------------------------------------*/
void kaobei()//拷贝文件到test1.txt
{
char ch;
ifstream file("C:\Users\niuniu\Desktop\drug.txt");//读取C盘文件
ofstream file1("C:\Users\niuniu\Desktop\test1.txt");//创建文本文件
while (file.get(ch))//读取文本内容
{
file1 << ch;//写入内容到文件
}
file.close();//关闭文件流
file1.close();//关闭文件流
cout << endl;
}
int line()
{
ifstream file1("C:\Users\niuniu\Desktop\test1.txt");//没有就创建
string str;
int line = 0;
while (file1)
{
getline(file1, str);
remove(str.begin(), str.end(), ' ');//删除从文件开始到结束中的空格
remove(str.begin(), str.end(), ' ');//删除从文件开始到结束中的空格
if (str.length() > 0)//如果有一行除去空格之后不为零就算作是一个对象
line++;
}
return line;
}
void read()/*从文件导入*/
{
system("cls");
ifstream ofile;
string nu; /*编号*/
string na; /*名称*/
float pr; /*单价*/
float co; /*销售数量*/
float sa; /*销售额*/
ofile.open("C:\Users\niuniu\Desktop\drug.txt", ios::in);
if (ofile.is_open())
{
for (int i = 1; i <= N; i++)
{
ofile >> nu >> na >> pr >> co >> sa;
l->r[i].num = nu;
l->r[i].name = na;
l->r[i].price = pr;
l->r[i].count = co;
l->r[i].sale = sa;
if (i >= N)
{
cout << "文件数据已经全部导入。" << endl;
cout << "当前药品数量:" << i << endl;
display(l);
}
}
}
else
{
cout << "打开文件时出错!" << endl;
}
ofile.close();
}
void write()/*将药品信息导出文件保存*/
{
ofstream ofile("C:\Users\niuniu\Desktop\drug_1.txt");
for (int i = 1; i <= N; i++)
{
ofile << l->r[i].num << " ";
ofile << l->r[i].name << " ";
ofile << l->r[i].price << " ";
ofile << l->r[i].count << " ";
ofile << l->r[i].sale << endl;
}
display(l);
cout << "所有药品信息都已成功保存!" << endl;
cout << "保存文件名:drug_1.txt" << endl;
}
/*---------------------------------------------------------*/
void mainjiemian()
{
cout << " ★-----★---------★---------★-----★" << endl;
cout << " 欢迎进入药品信息管理系统 " << endl;
cout << " ☆ ☆" << endl;
cout << " 1 导入药品信息 " << endl;
cout << " ☆ 2 导出药品信息 ☆" << endl;
cout << " 3 编号排序 " << endl;
cout << " ☆ 4 单价排序 ☆" << endl;
cout << " 5 销售额排序 " << endl;
cout << " ☆ 6 销售量排序 ☆" << endl;
cout << " 7 退出管理系统 " << endl;
cout << " ☆ ☆" << endl;
cout << " MADE IN CHINA " << endl;
cout << " ★-----★---------★---------★-----★" << endl;
cout << endl;
cout << endl;
cout << "请选择数字命令:";
}
void jieshu()//结束显示
{
cout << " ★-----★---------★---------★-----★" << endl;
cout << endl;
cout << " ☆ 感谢您的使用! ☆" << endl;
cout << endl;
cout << " ★-----★---------★---------★-----★" << endl;
cout << endl;
}
/*-------------------------------------------------------*/
void copy(Sequnenlist * l, int i, int j)
{
l->r[i].count = l->r[j].count;
l->r[i].name = l->r[j].name;
l->r[i].num = l->r[j].num;
l->r[i].price = l->r[j].price;
l->r[i].sale = l->r[j].sale;
}
/*-------------------------------------------------------*/
void shift(Sequnenlist * l, int i, int m)/*堆排序调用函数*/
{
Datatype temp;
temp.count = l->r[i].count;
temp.name = l->r[i].name;
temp.num = l->r[i].num;
temp.price = l->r[i].price;
temp.sale = l->r[i].sale;
for (int j = 2 * i; j <= m; j = j * 2)
{
if ((j < m) && (l->r[j].sale < l->r[j + 1].sale))
{
j++;
}
if (temp.sale >= l->r[j].sale)
{
break;
}
else
{
copy(l, i, j);
i = j;
}
}
l->r[i].count = temp.count;
l->r[i].name = temp.name;
l->r[i].num = temp.num;
l->r[i].price = temp.price;
l->r[i].sale = temp.sale;
}
void heap_sort(Sequnenlist * l)/*堆排序*/
{
int n = l->length;
for (int i = n / 2; i >= 1; i--)
{
shift(l, i, n);
}
for (int i = n; i > 1; i--)
{
Swap(l, 1, i);
shift(l, 1, i - 1);
}
}
/*-----------------------------------------------------*/
void bubble_sort(Sequnenlist * l)/*冒泡排序*/
{
int noswap = 0;
for (int i = 1; i < l->length; i++)
{
noswap = 1;
for (int j = l->length; j >= i + 1; j--)
{
if (l->r[j].price < l->r[j - 1].price)
{
Swap(l, j, j - 1);
noswap = 0;
}
}
if (noswap)
break;
}
}
/*--------------------------------------------------------*/
int partion(Sequnenlist * l, int low, int high)/*快速排序*/
{
float pivotkey = l->r[low].count;/*选择成绩1作为中枢轴*/
while (low < high)
{
while (low < high&&l->r[high].count >= pivotkey)
{
high--;
}
Swap(l, low, high);
while (low < high&&l->r[low].count <= pivotkey)
{
low++;
}
Swap(l, low, high);
}
return low;
}
void quick_sort(Sequnenlist * l, int low, int high)/*快速排序*/
{
int i;
if (low < high)
{
i = partion(l, low, high);
quick_sort(l, low, i - 1);
quick_sort(l, i + 1, high);
}
}
/*-------------------------------------------------------*/
/*队列的基本操作*/
void init_queue(Linkqueue * q)/*队列初始化*/
{
q->front = new Lnode;
q->front->data.num = "null";
q->front->data.name = "null";
q->front->data.price = 0;
q->front->data.count = 0;
q->front->data.sale = 0;
q->front->next = NULL;
q->rear = q->front;
}
bool empty_queue(Linkqueue * q)/*判断便道是否为空*/
{
if (q->front->next == NULL&& q->rear->next == NULL)
return true;
else
return false;
}
void en_queue(Linkqueue * q, Datatype x)/*药品进入便道*/
{
Lnode * p = new Lnode;
p->data = x;
p->next = NULL;
if (empty_queue(q))
{
q->front->next = p;
q->rear = p;
}
else
{
q->rear->next = p;
q->rear = p;
q->rear->next = NULL;
}
}
Datatype de_queue(Linkqueue * q)/*药品从队列中取出*/
{
if (empty_queue(q))
{
Datatype y;
return y;
}
else
{
Lnode * p = new Lnode;
p = q->front->next;
Datatype x = p->data;
q->front->next = p->next;
if (empty_queue(q))
{
q->front->data.num = "null";
q->front->data.name = "null";
q->front->data.price = 0;
q->front->data.count = 0;
q->front->data.sale = 0;
q->front->next = NULL;
q->rear = q->front;
}
free(p);
return x;
}
}
void math_sort(Sequnenlist * l)/*基数排序*/
{
Linkqueue * a = new Linkqueue; Linkqueue * b = new Linkqueue; Linkqueue * c = new Linkqueue; Linkqueue * d = new Linkqueue; Linkqueue * e = new Linkqueue;
Linkqueue * f = new Linkqueue; Linkqueue * g = new Linkqueue; Linkqueue * h = new Linkqueue; Linkqueue * i = new Linkqueue; Linkqueue * j = new Linkqueue;
Linkqueue * k = new Linkqueue; Linkqueue * ll = new Linkqueue; Linkqueue * m = new Linkqueue; Linkqueue * n = new Linkqueue; Linkqueue * o = new Linkqueue;
Linkqueue * p = new Linkqueue; Linkqueue * q = new Linkqueue; Linkqueue * r = new Linkqueue; Linkqueue * s = new Linkqueue; Linkqueue * t = new Linkqueue;
Linkqueue * u = new Linkqueue; Linkqueue * v = new Linkqueue; Linkqueue * w = new Linkqueue; Linkqueue * x = new Linkqueue; Linkqueue * y = new Linkqueue; Linkqueue * z = new Linkqueue;
init_queue(a); init_queue(b); init_queue(c); init_queue(d); init_queue(e); init_queue(f); init_queue(g); init_queue(h); init_queue(i); init_queue(j);
init_queue(k); init_queue(ll); init_queue(m); init_queue(n); init_queue(o); init_queue(p); init_queue(q); init_queue(r); init_queue(s); init_queue(t);
init_queue(u); init_queue(v); init_queue(w); init_queue(x); init_queue(y); init_queue(z);
for (int ii = 3; ii >= 0; ii--)
{
if (ii != 0)
{
/*数字全部走一遍,进入到不同的队列中*/
for (int jj = 1; jj <= N; jj++)
{
if (l->r[jj].num[ii] == '9')
{
en_queue(j, l->r[jj]);
}
else if (l->r[jj].num[ii] == '8')
{
en_queue(i, l->r[jj]);
}
else if (l->r[jj].num[ii] == '7')
{
en_queue(h, l->r[jj]);
}
else if (l->r[jj].num[ii] == '6')
{
en_queue(g, l->r[jj]);
}
else if (l->r[jj].num[ii] == '5')
{
en_queue(f, l->r[jj]);
}
else if (l->r[jj].num[ii] == '4')
{
en_queue(e, l->r[jj]);
}
else if (l->r[jj].num[ii] == '3')
{
en_queue(d, l->r[jj]);
}
else if (l->r[jj].num[ii] == '2')
{
en_queue(c, l->r[jj]);
}
else if (l->r[jj].num[ii] == '1')
{
en_queue(b, l->r[jj]);
}
else if (l->r[jj].num[ii] == 0)
{
en_queue(a, l->r[jj]);
}
}//end
/*再从不同的队列中依次取出放入到原来的顺序表中*/
int kk = 1;
while (!empty_queue(a))
{
l->r[kk] = de_queue(a);
kk++;
}
while (!empty_queue(b))
{
l->r[kk] = de_queue(b);
kk++;
}
while (!empty_queue(c))
{
l->r[kk] = de_queue(c);
kk++;
}
while (!empty_queue(d))
{
l->r[kk] = de_queue(d);
kk++;
}
while (!empty_queue(e))
{
l->r[kk] = de_queue(e);
kk++;
}
while (!empty_queue(f))
{
l->r[kk] = de_queue(f);
kk++;
}
while (!empty_queue(g))
{
l->r[kk] = de_queue(g);
kk++;
}
while (!empty_queue(h))
{
l->r[kk] = de_queue(h);
kk++;
}
while (!empty_queue(i))
{
l->r[kk] = de_queue(i);
kk++;
}
while (!empty_queue(j))
{
l->r[kk] = de_queue(j);
kk++;
}
}
else if (ii==0)
{
/*数字全部走一遍,进入到不同的队列中*/
for (int jj = 1; jj <= N; jj++)
{
if (l->r[jj].num[ii] == 'A')
{
en_queue(a, l->r[jj]);
}
else if (l->r[jj].num[ii] =='B')
{
en_queue(b, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'C')
{
en_queue(c, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'D')
{
en_queue(d, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'E')
{
en_queue(e, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'F')
{
en_queue(f, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'G')
{
en_queue(g, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'H')
{
en_queue(h, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'I')
{
en_queue(i, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'J')
{
en_queue(j, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'K')
{
en_queue(k, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'L')
{
en_queue(ll, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'M')
{
en_queue(m, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'N')
{
en_queue(n, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'O')
{
en_queue(o, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'P')
{
en_queue(p, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'Q')
{
en_queue(q, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'R')
{
en_queue(r, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'S')
{
en_queue(s, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'T')
{
en_queue(t, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'U')
{
en_queue(u, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'V')
{
en_queue(v, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'W')
{
en_queue(w, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'X')
{
en_queue(x, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'Y')
{
en_queue(y, l->r[jj]);
}
else if (l->r[jj].num[ii] == 'Z')
{
en_queue(k, l->r[jj]);
}
}//end
/*再从不同的队列中依次取出放入到原来的顺序表中*/
int kk = 1;
while (!empty_queue(a))
{
l->r[kk] = de_queue(a);
kk++;
}
while (!empty_queue(b))
{
l->r[kk] = de_queue(b);
kk++;
}
while (!empty_queue(c))
{
l->r[kk] = de_queue(c);
kk++;
}
while (!empty_queue(d))
{
l->r[kk] = de_queue(d);
kk++;
}
while (!empty_queue(e))
{
l->r[kk] = de_queue(e);
kk++;
}
while (!empty_queue(f))
{
l->r[kk] = de_queue(f);
kk++;
}
while (!empty_queue(g))
{
l->r[kk] = de_queue(g);
kk++;
}
while (!empty_queue(h))
{
l->r[kk] = de_queue(h);
kk++;
}
while (!empty_queue(i))
{
l->r[kk] = de_queue(i);
kk++;
}
while (!empty_queue(j))
{
l->r[kk] = de_queue(j);
kk++;
}
while (!empty_queue(k))
{
l->r[kk] = de_queue(k);
kk++;
}
while (!empty_queue(ll))
{
l->r[kk] = de_queue(ll);
kk++;
}
while (!empty_queue(m))
{
l->r[kk] = de_queue(m);
kk++;
}
while (!empty_queue(n))
{
l->r[kk] = de_queue(n);
kk++;
}
while (!empty_queue(o))
{
l->r[kk] = de_queue(o);
kk++;
}
while (!empty_queue(p))
{
l->r[kk] = de_queue(p);
kk++;
}
while (!empty_queue(q))
{
l->r[kk] = de_queue(q);
kk++;
}
while (!empty_queue(r))
{
l->r[kk] = de_queue(r);
kk++;
}
while (!empty_queue(s))
{
l->r[kk] = de_queue(s);
kk++;
}
while (!empty_queue(t))
{
l->r[kk] = de_queue(t);
kk++;
}
while (!empty_queue(u))
{
l->r[kk] = de_queue(u);
kk++;
}
while (!empty_queue(v))
{
l->r[kk] = de_queue(v);
kk++;
}
while (!empty_queue(w))
{
l->r[kk] = de_queue(w);
kk++;
}
while (!empty_queue(x))
{
l->r[kk] = de_queue(x);
kk++;
}
while (!empty_queue(y))
{
l->r[kk] = de_queue(y);
kk++;
}
while (!empty_queue(z))
{
l->r[kk] = de_queue(z);
kk++;
}
}
}
}
/*-------------------------------------------------------*/
int main()
{
system("color 57");
int line_file;//文件里的药品数
kaobei();//拷贝文件
line_file = line();
N = line_file - 1;
l->length = N;
char*end;/*末端指针*/
string order;
mainjiemian();
while (cin >> order)
{
int a_order = static_cast<int>(strtol(order.c_str(), &end, 10));/*将输入进来的值转化为int类型*/
switch (a_order + 48)
{
case'1':
{
read();
system("pause");
system("cls");
mainjiemian();
break;
}
case'2':
{
system("cls");
write();
system("pause");
system("cls");
mainjiemian();
break;
}
case'3':
{
system("cls");
math_sort(l);
display(l);
system("pause");
system("cls");
mainjiemian();
break;
}
case'4':
{
system("cls");
bubble_sort(l);
display(l);
system("pause");
system("cls");
mainjiemian();
break;
}
case'5':
{
system("cls");
heap_sort(l);
display(l);
system("pause");
system("cls");
mainjiemian();
break;
}
case'6':
{
system("cls");
quick_sort(l, 1, N);
display(l);
system("pause");
system("cls");
mainjiemian();
break;
}
case'7':
{
system("cls");
jieshu();
return 0;
break;
}
default:
{
cin.clear();
cin.sync();
cout << "输入错误,重新返回主界面。" << endl;
system("pause");
system("cls");
mainjiemian();
break;
}
}
}
return 0;
}drug药品内容如下:
W123 忘情水 9.9 50 495
X256 相思豆 12 40 480
B852 回魂丹 8 20 160
D584 大力丸 10 33 330
M665 孟婆汤 8.4 20 168
Y532 隐身草 6.6 23 151.8
R423 软筋散 13 42 546