- 需求分析
【提示:以无歧义的陈述说明程序设计的任务,主要说明内容是程序要做什么。并明确规定:(1) 输入的形式和输入值的范围;(2) 输出的形式;(3) 程序所能达到的功能。】
图书信息管理:
定义一个包含图书信息(书号、书名、 价格)的顺序表.
- 输入图书信息
功能:录入图书信息
【输入】: n+1 行
前 n 行: n 本图书的信息:书号、 书名、价格
第 n+1 行:输入结束标志:0 0 0(空格分隔的三个 0)
每本图书信息占一行,用空格分隔,价格之后没有空格,书号 和书名为字符串类型char[ ],价格float。
【输出】:n+1行
第1行:图书数目
后n行:图书信息(价格保留2位小数
(2)计算平均价格,调整价格。
功能:计算所有图书对的平均价格。将所有低于平均价格的图书价格提高 20%,
所有高于或等于平均价格的图书价格提高 10%
【输入】:同(1)
【输出】:n+1行
第1行:修改前所有图书平均价格
后n行:修改后n本图书信息
每本图书信息占一行,用空格分隔,价格之后没有空格,书号 和书名为字符串类型char[ ],价格float保留2位。
- 查找价格最高的图书
【输出】: m+1 行
第1行:最贵图书的数目(可能多本)
后 m行:最贵图书的信息
(4)根据指定的待入库的新图书的位置和信息
【输入】: n+3 行
第 1 行:图书数目 n
后 n 行: n 本图书的信息 (书号、书名、价格),每本图书信息占一行,书号、书名、价格用空格分隔
第 n+2 行:输入一个整数,代表待入库的新图书的位置序号。
第 n+3 行:内容 为新图书的信息,书号、书名、价格用空格分隔。
【输出】:
若插入成功:输出更新后所有图书的信息(书号、书名、价格)总计 n+1 行;
若插入失败:输出“抱歉,入库位置非法!”。
(5)根据指定待出库的旧图书位置,将该图书从图书表中删除
【输入】 n+23 行
第 1 行:图书数目 n
后 n 行: n 本图书的信息(书号、书名、价格)
第 n+2 行:输入一个整数,代表待删除的新图书的位置序号。
【输出】:
若删除成功:输出旧图书出库后所有图书的信息(书 号、书名、价格)
总计 n-1 行,每行是一本图书的信息
若删除失败:只输出以下提示:抱歉, 出库位置非法!
- 概要设计
【提示:说明设计中用到的抽象数据类型的定义、主程序的流程图。】
1.基于链表的图书管理系统:
ADT:
typedef struct {
char id[100];//书号
char name[100];//书名
float price;//图书价格
} Book;
typedef struct LNode {
Book data;//图书
struct LNode* next;
} LNode, * LinkList;
函数:
void printBooks(LinkList L)
void input(LinkList* L)
float Average(LinkList L)
void changeprice(LinkList L, float aver)
void FM(LinkList L)
void insertBook(LinkList* L, int index, Book b)
void deleteBook(LinkList* L, int i)
- 基于顺序表的图书管理系统:
ADT:
//图书结构
typedef struct{
char id[100];//书号
char name[100];//书名
float price;//价格
}BOOK;
//基于顺序表的图书列表
typedef struct{
BOOK *book;//图书
int length;
}BookList;
函数:
int InitList(BookList *blist)
void inputBook(BookList *L)
void PrintBookList(BookList blist)
float Average_Modify(BookList *blist)
void Find(BookList blist)
void InsertList(BookList *L)
void DeleteList(BookList *L)
- 详细设计
【提示:实现概要设计中定义的主要数据类型,并实现其中的基本操作和主程序等。】
- 基于链表的图书管理系统:
ADT:
typedef struct {
char id[100];//书号
char name[100];//书名
float price;//图书价格
} Book;
typedef struct LNode {
Book data;//图书
struct LNode* next;
} LNode, * LinkList;
函数:
void printBooks(LinkList L)
void input(LinkList* L)//输入图书信息
float Average(LinkList L)//求图书价格平均值
void changeprice(LinkList L, float aver)//调整图书价格
void FM(LinkList L)//寻找图书价格最高的图书的信息
void insertBook(LinkList* L, int index, Book b)//插入图书
void deleteBook(LinkList* L, int i)//删除图书
int main(){
BookList blist;
int choice;
float average;
int status,p=1;
printf("【1. 输入图书信息\n");
printf("【2. 计算平均价格并调整价格\n");
printf("【3. 查找最贵的图书\n");
printf("【4. 插入新图书\n");
printf("【5. 删除旧图书\n");
printf("【0. 退出\n");
while(p==1){
printf("请输入你的选择:");
scanf("%d", &choice);
switch (choice){
case 1:
status =InitList(&blist);
printf("1");
//录入图书信息
if(status==OK){
inputBook(&blist);
}
//输出图书信息
printf("现有图书馆内图书书目为%d\n图书馆内所有图书信息依次为:\n",blist.length);//图书书目
PrintBookList(blist);
printf("\n");
break;
case 2:
//输出图书均价
average=Average_Modify(&blist);
printf("现图书馆内图书平均价格为%.2f \n调整图书价格后,图书馆内所有图书信息为:\n",average);
//输出修改价格后图书信息
PrintBookList(blist);
printf("\n");
break;
case 3:
//查找价格最高图书
Find(blist);
break;
case 4:
//插入
InsertList(&blist);
break;
case 5:
DeleteList(&blist);
printf("删除成功后,图书馆内所有图书信息为\n");
PrintBookList(blist);
break;
case 0:
p=0;
break;
default:
printf("无效的选择,请重新输入。\n");
}
}
return 0;
}
2.基于顺序表的图书管理系统:
//图书结构
typedef struct{
char id[100];//书号
char name[100];//书名
float price;//价格
}BOOK;
//基于顺序表的图书列表
typedef struct{
BOOK *book;//图书
int length;
}BookList;
函数:
int InitList(BookList *blist)//初始化BookList类型变量
void inputBook(BookList *L)//输入图书信息
void PrintBookList(BookList blist)//打印图书信息
float Average_Modify(BookList *blist)//求图书价格平均值并对价格进行调整
void Find(BookList blist)//寻找价格最高的图书信息
void InsertList(BookList *L)//插入新图书
void DeleteList(BookList *L)//删除图书
主函数:
int main() {
LinkList L=0;
int choice,i;
float ave;
Book b;
do {
printf("【1. 输入所有图书信息\n");
printf("【2. 求平均价格并且调整价格\n");
printf("【3. 查找最贵图书并输出\n");
printf("【4. 插入新图书\n");
printf("【5. 删除旧图书\n");
printf("【0. 退出\n");
scanf("%d", &choice);
switch (choice) {
case 1:
input(&L);
printBooks(L);
break;
case 2:
ave = Average(L);
printf("平均价格:%.2f\n", ave);
changeprice(L, ave);
printBooks(L);
break;
case 3:
FM(L);
break;
case 4:
printf("新图书的位置:");
scanf("%d", &i);
printf("新图书的信息(书号、书名、价格):");
scanf("%s %s %f", b.id, b.name, &b.price);
insertBook(&L, i,b);
printBooks(L);
break;
case 5:
printf("要删除的图书位置:");
scanf("%d", &i);
deleteBook(&L, i);
printBooks(L);
break;
case 0:
break;
default:
printf("NO! please choose again\n");
}
} while (choice != 0);
return 0;
}
- 调试分析
【提示:(1) 调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分析;(2) 算法的时空分析(包括基本操作和其他算法的时间复杂度和空间复杂度的分析)和改进设想;(3) 经验和体会等。】
- 基于链表的图书管理系统算法的时空分析:
1.为时间复杂度:2.为空间复杂度
void printBooks(LinkList L)//打印图书信息 1.0(n) 2.O(1)
void input(LinkList* L)//输入图书信息 1.0(n) 2.O(1)
float Average(LinkList L)//求图书价格平均值 1.0(n) 2.O(1)
void changeprice(LinkList L, float aver)//调整图书价格 1.0(n) 2.O(1)
void FM(LinkList L)//寻找图书价格最高的图书的信息 1.0(n) 2.O(1)
void insertBook(LinkList* L, int index, Book b)//插入图书 1.0(n) 2.O(1)
void deleteBook(LinkList* L, int i)//删除图书 1.0(n) 2.O(1)
(2)基于顺序表的图书管理系统的时空分析:
int InitList(BookList *blist)//初始化BookList类型变量 : 1.0(1) 2.O(1)
void inputBook(BookList *L)//输入图书信息 1.0(n) 2.0(1)
void PrintBookList(BookList blist)//打印图书信息 1.0(n) 2.0(1)
float Average_Modify(BookList *blist)//求价格平均值并对调整 1.0(n) 2.0(1)
void Find(BookList blist)//寻找价格最高的图书信息 1.0(n) 2.0(n)
void InsertList(BookList *L)//插入新图书 1.0(n) 2.0(1)
void DeleteList(BookList *L)//删除图书 1.0(n) 2.0(1)
- 遇到的问题:
- 在顺序表插入算法中,对于新插入的图书我第一次用Book *e存放相关信息,发现计算机自动将数据放入了原有顺序表BookList L的L->book[0]中,于是乎我重新定义BookList E,用 E->book[0]存放相关信息就不会出现错误赋值的现象 ;
- 在链表的主函数中,我原本只用do while语句不能实现选择循环,后添加进while(1)才进入选择循环。
- 经验与体会:
项目实验的练习比 平时在oj和力扣上面的算法练习更加具有结构系统的完整,需要考虑到很多数据的衔接与传输。oj的算法练习可以作为项目实验的小模块基础,但是更加完善的项目实验则需要更加缜密的思维和夯实的基础。就像左老师说的作为软件工程的学生,对于大型软件的设计开发才是主线任务。
同时,这次实验也让我更加重视我往后学习的重点和时间安排的合理性。
- 测试数据与结果
【提示:列出程序测试结果,包括输入和输出。测试数据应尽可能完整和严格,考虑异常值的处理。】
1.基于链表的图书管理系统: