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(), '\t');//刪除從文件開始到結束中的空格 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 << "\t"; ofile << l->r[i].name << "\t"; ofile << l->r[i].price << "\t"; ofile << l->r[i].count << "\t"; 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