**
图书信息管理系统预习报告
**
要求:
设计并实现一个图书信息管理系统。根据实验要求设计该系统的菜单和交互逻辑,并编码实现增删改查的各项功能。 该系统至少包含以下功能:(1) 根据指定图书个数,逐个输入图书信息;(2) 逐个显示图书表中所有图书的相关信息;(3) 能根据指定的待入库的新图书的位置和信息,将新图书插入到图书表中指定的位置;(4) 根据指定的待出库的旧图书的位置,将该图书从图书表中删除;(5) 能统计表中图书个数;(遍历)(6) 实现图书信息表的图书去重;(7) 实现最爱书籍查询,根据书名进行折半查找,要求使用非递归算法实现,成功返回此书籍的书号和价格;(8) 图书信息表按指定条件进行批量修改;(9) 利用快速排序按照图书价格降序排序;实现最贵图书的查找;
相应功能实现:
cout << " 1.插入数据(逻辑位置,>0)" << endl;
template < class T >
void SeqList<T>::Insert(int i, T x) {
if (length >= MaxSize) cout<< "上溢"<<endl;
if (i<1 || i>length + 1) cout<< "位置错误"<<endl;
for (int j = length; j >= i; --j) { //遍历调整元素位置;
data[j] = data[j - 1];
}
data[i - 1] = x;//同时改变length
++length;
}
cout << " 2.删除某数据(逻辑位置,>0)" << endl;
template < class T >
T SeqList<T>::Delete(int i) {
if (length == 0) cout << "下溢" << endl;
if (i<1 || i>length) cout<< "位置错误"<<endl;
T x = data[i - 1];
for (int j = i; j < length; ++j) {
data[j - 1] = data[j]; //删除的元素后的元素全部前移动一位,以达到删除的目的;
}
--length;//同时改变length
return x;
}
cout << " 3.查找某数据(逻辑位置,>0)" << endl;
template < class T >
void PrintSd(T s) { //输出指定位置元素;
cout << "书号 书名 价格" << endl;
cout << "----------------------------" << endl;
cout << s.no << setw(9) << s.name << setw(9) << s.price << endl;
cout << "----------------------------" << endl;
}
cout << " 4.输出所有数据" << endl;
template < class T >
void PrintList(SeqList<T> d) { //全部输出;
cout << " 书数: "<<d.GetLength() << endl;
if (d.GetLength() > 0) {//有书输出
cout << "书号 书名 价格" << endl;
cout << "----------------------------" << endl;
for (int i = 1; i <= d.GetLength(); ++i) {
Book s = d.Get(i);
cout << s.no << setw(9) << s.name << setw(9) << s.price << endl;
}
cout << "----------------------------" << endl;
}
else {//无书
cout << "无记录" << endl;
}
}
cout << " 5.输出数据数量" << endl;
int GetLength() { return length; } //求顺序表的长度
cout << " 6.书号去重 " << endl;
template < class T >
void SeqList<T>::RpDelete() {
for (int i = 0; i <=length; ++i) {//双重循环
for(int j=i+1;j <=length;++j)
if (data[i].no==data[j].no) {
Delete(j+1);
}
}
cout << " 去重成功!" << endl;
}
cout << " 7.书名二分查找" << endl;
template < class T >
int SeqList<T>::BiSearch(string x) {
int low = 0;
int high = length - 1;
int mid = 0;
double key = 0;//查找依据
for (int i = 0; i < length - 1; i++) {//书名转化价格查找
if (data[i].name == x) {
key = data[i].price;
}
}
while (low <= high) {//逐步缩小范围
mid = (low + high) / 2;
if (data[mid].price > key)
low = mid + 1;
else if (data[mid].price < key)
high = mid - 1;
else
return mid;
}
return -1;
}
cout << " 8.批量修改" << endl;
template < class T >
void SeqList<T>::Adjust() {
double sum = 0;//求和
for (int i = 0; i < length-1; ++i) {
sum += data[i].price;
}
double ave = sum / (length-1);//求平均
//调整
for (int i = 0; i < length-1 ; ++i) {
if (data[i].price < ave) {
data[i].price += 0.2 * data[i].price; }else {
data[i].price += 0.1 * data[i].price;
}
}
cout << "平均价格" << ave << endl;
}
cout << " 9.快排" << endl;
template < class T >
void SeqList<T>::QuickSort(int low,int high){
if(low<high) //递归终止条件
{
int i = low, j = high;
T x = data[low];
while(i<j) {
while(i<j && data[j].price <= x.price) j--; //先从右边开始
if(i<j) data[i++]= data[j];
while(i<j && data[i].price >= x.price) i++; if(i<j) data[j--]= data[i]; }
data[i] = x; //i已经排列好 QuickSort(low ,i-1);//递归
QuickSort(i+1 ,high);
}
}
主函数用了文件流:
效果截图:
总结:
代码由一个结构体Book,一个SeqList类,一个主函数组成;主函数用了一个文件流输入,当然也可不用,用插入函数输入数据;书名二分查找要先把书名转化为书价,再快速排序书价,再二分查找书价;快速排序注意先右边遍历;我把结构体Book中的两个char数组改用了string变量;
完整代码:
#include<iostream>
#include<string>
#include<fstream>
#include<iomanip>
#include<algorithm>
using namespace std;
#define MaxSize 100
typedef struct {
string no; //书号
string name; //书名
double price; //价格
}Book;
template < class T >
class SeqList
{
public:
SeqList() { length = 0; } //无参构造函数
SeqList(T a[], int n); //有参构造函数
~SeqList(); //析构函数为空
int GetLength() { return length; } //求顺序表的长度
T Get(int i); //取顺序表的第i个元素(i为逻辑号)
void Insert(int i, T x); //在顺序表中第i个位置插入值为x的元素(i为逻辑号)
T Delete(int i);//删除顺序表的第i个元素(i为逻辑号)
void RpDelete();//去重
int BiSearch(string x);//书名二分查找
void Adjust();//价格调整
void QuickSort(int low, int high);//价格降序排列
private:
T data[MaxSize]; //存放书数据的数组
int length; //顺序表的长度
};
template < class T >
SeqList<T>::SeqList(T a[], int n) { //有参构造函数
if (n > MaxSize) cout << "参数错误" << endl;
for (int i = 0; i < n; ++i) {
data[i] = a[i];
}
length = n;//初始化
}
template < class T >
T SeqList<T>::Get(int i) { //取顺序表的第i个元素
if (i > 0 && i <= length) //保证i不会引起数组overflow;
return data[i - 1];
}
template < class T >
void SeqList<T>::Insert(int i, T x) {
if (length >= MaxSize) cout << "上溢" << endl;
if (i<1 || i>length + 1) cout << "位置错误" << endl;
for (int j = length; j >= i; --j) { //遍历调整元素位置;
data[j] = data[j - 1];
}
data[i - 1] = x;//同时改变length
++length;
}
template < class T >
T SeqList<T>::Delete(int i) {
if (length == 0) cout << "下溢" << endl;
if (i<1 || i>length) cout << "位置错误" << endl;
T x = data[i - 1];
for (int j = i; j < length; ++j) {
data[j - 1] = data[j]; //删除的元素后的元素全部前移动一位,以达到删除的目的;
}
--length;//同时改变length
return x;
}
template < class T >
void SeqList<T>::RpDelete() {
for (int i = 0; i <= length; ++i) {//双重循环
for (int j = i + 1; j <= length; ++j)
if (data[i].no == data[j].no) {
Delete(j + 1);
}
}
cout << " 去重成功!" << endl;
}
template < class T >
int SeqList<T>::BiSearch(string x) {
int low = 0;
int high = length - 1;
int mid = 0;
double key = 0;//查找依据
for (int i = 0; i < length - 1; i++) {//书名转化价格
if (data[i].name == x) {
key = data[i].price;
}
}
while (low <= high) {//逐步缩小范围
mid = (low + high) / 2;
if (data[mid].price > key)
low = mid + 1;
else if (data[mid].price < key)
high = mid - 1;
else
return mid;
}
return -1;
}
template < class T >
void SeqList<T>::Adjust() {
double sum = 0;//求和
for (int i = 0; i < length - 1; ++i) {
sum += data[i].price;
}
double ave = sum / (length - 1);//求平均
//调整
for (int i = 0; i < length - 1; ++i) {
if (data[i].price < ave) {
data[i].price += 0.2 * data[i].price;
}
else {
data[i].price += 0.1 * data[i].price;
}
}
cout << "平均价格" << ave << endl;
}
template < class T >
void SeqList<T>::QuickSort(int low, int high) {
if (low < high) //递归进入条件
{
int i = low, j = high;
T x = data[low];
while (i < j) {
while (i < j && data[j].price <= x.price) j--; //先从右边开始
if (i < j) data[i++] = data[j];
while (i < j && data[i].price >= x.price) i++;
if (i < j) data[j--] = data[i];
}
data[i] = x;
QuickSort(low, i - 1);
QuickSort(i + 1, high);
}
}
template < class T >
SeqList<T>::~SeqList() {
}
template < class T >
void PrintList(SeqList<T> d) { //全部输出;
cout << " 书数: " << d.GetLength() << endl;
if (d.GetLength() > 0) {//有书输出
cout << "书号 书名 价格" << endl;
cout << "----------------------------" << endl;
for (int i = 1; i <= d.GetLength(); ++i) {
Book s = d.Get(i);
cout << s.no << setw(9) << s.name << setw(9) << s.price << endl;
}
cout << "----------------------------" << endl;
}
else {//无书
cout << "无记录" << endl;
}
}
template < class T >
void PrintSd(T s) { //输出指定位置元素;
cout << "书号 书名 价格" << endl;
cout << "----------------------------" << endl;
cout << s.no << setw(9) << s.name << setw(9) << s.price << endl;
cout << "----------------------------" << endl;
}
int main() {
ifstream f;//调用外部文件;
int w;//键盘输入的数据位置;
int op; //switch选case的凭依;
Book tem; // 辅助SeqList<Sd> s的函数Insert()使用;
SeqList<Book> s;//定义顺序表对象;
char ny; //辅助选y或n用;
string na;//辅助输入名字;
int whi = 1; //菜单进入和跳出的条件;
int wh = 1;//菜单case1循环输入;
cout << "使用已有的数据输入:y或者不使用输入:n" << endl;
cin >> ny;
while (1) {//文件流
if (ny == 'y') {
f.open("书.txt", ios::in);
if (!f) {
cout << "不存在文件书.txt" << endl;
continue;
}
else {
cout << "存在文件书.txt" << endl;
int i = 0;
while (!f.eof()) {
f >> tem.no >> tem.name >> tem.price;
s.Insert(i + 1, tem);
++i;
}
}
f.close();
break;
}
else if (ny == 'n') {
break;
}
}
while (whi) {
cout << " 主菜单 " << endl;
cout << " 1.插入数据(逻辑位置,>0)" << endl;
cout << " 2.删除某数据(逻辑位置,>0)" << endl;
cout << " 3.查找某数据(逻辑位置,>0)" << endl;
cout << " 4.输出所有数据" << endl;
cout << " 5.输出数据数量" << endl;
cout << " 6.书号去重 " << endl;
cout << " 7.书名二分查找" << endl;
cout << " 8.批量修改" << endl;
cout << " 9.快排" << endl;
cout << " 10.退出" << endl;
cout << " 输入(1~10) " << endl;
cin >> op;
switch (op) {
case 1:
while (wh) {
cout << "请输入插入数据位置(逻辑位置,>0)" << endl;
cin >> w;
cout << "请输入书号,名字,价格" << endl;
cin >> tem.no;
cin >> tem.name;
cin >> tem.price;
s.Insert(w, tem);
if (tem.price == 0) {//按要求退出插入;
break;
}
}
break;
case 2:
cout << "请输入删除数据位置(逻辑位置,>0)" << endl;//按位置删
cin >> w;
s.Delete(w);
break;
case 3:
cout << "请输入查找数据位置(逻辑位置,>0)" << endl;//按名字查找
cin >> w;
PrintSd(s.Get(w));
break;
case 4:
PrintList(s);
break;
case 5:
cout << "数量: " << s.GetLength() << endl;//数量
break;
case 6:
s.RpDelete();//去重
PrintList(s);
break;
case 7:
s.QuickSort(0, s.GetLength() - 1);//二分查找先快排,因为二分只能在有序的元素队中找
cout << "name:";
cin >> na;
PrintSd(s.Get(s.BiSearch(na) + 1));
break;
case 8:
s.Adjust();//按要求的调整
PrintList(s);
break;
case 9:
s.QuickSort(0, s.GetLength() - 1);//快速排序,0, s.GetLength() - 1的输入方式必要,因为函数中要用到递归
PrintList(s);
break;
case 10:
whi = 0;//退出
default:continue;
}
}
return 0;
}