**图书查询系统**
1、数据结构课程设计
2、题目要求
3、需求分析
4、系统设计
5、功能设计
6、排序算法
7、String比较方法
8、字典排序
9、查找算法
10、IO流设计
11、存储结构
12、类设计
13、类成员
14、结束
15、源代码
Book.java
import java.io.*;
import java.util.*;
public class Book implements Serializable{ //使用Serializable接口,使Book对象序列化,便于使用对象流存入文件。
String[] attribute;
static int amount;
Scanner re=new Scanner(System.in);
/*
*主属性(primary attribute):征订号
*主码(primary key):征订号
*
*
***属性**** **编号**
*本季征订号 0
*分册 1
*出版社 2
*ISBN 3
*书名 4
*著作者 5
*适用分级 6
*价格 7
*出版年月 8
*社内分类 9
*中图法分类 10
*学科分类编码 11
*学科分类1 12
*学科分类2 13
*
*/
public void setAttribute(int i){
this.attribute[i]=re.next();
}
public String getAttribute(int i){
return this.attribute[i];
}
public Book() { //无参构造方法
}
public Book(String[] s){
this.attribute=new String[this.amount]; //初始化该数组;长度为表头属性个数
for(int i=0;i<s.length;i++){
this.attribute[i]=s[i]; //为该图书各个属性赋值
}
}
public void ruleToString(){
System.out.println("\t ***属性**** **属性值**\n");
System.out.println("\t *本季征订号 "+this.attribute[0]);
System.out.println("\t *分册 "+this.attribute[1]);
System.out.println("\t *出版社 "+this.attribute[2]);
System.out.println("\t *ISBN "+this.attribute[3]);
System.out.println("\t *书名 "+this.attribute[4]);
System.out.println("\t *著作者 "+this.attribute[5]);
System.out.println("\t *适用分级 "+this.attribute[6]);
System.out.println("\t *价格 "+this.attribute[7]);
System.out.println("\t *出版年月 "+this.attribute[8]);
System.out.println("\t *社内分类 "+this.attribute[9]);
System.out.println("\t *中图法分类 "+this.attribute[10]);
System.out.println("\t *学科分类编码 "+this.attribute[11]);
System.out.println("\t *学科分类1 "+this.attribute[12]);
System.out.println("\t *学科分类2 "+this.attribute[13]);
System.out.println("\t-----------------------------");
}
public String toString(){ //重写toString()方法
String str=attribute[0];
for(int j=1;j<attribute.length;j++){
str=str.concat(",");
str=str.concat(attribute[j]); //将指定字符串连接到此字符串的结尾。
}
return str;
}
}
Lirary.java
import java.io.*;
import java.util.*;
public class Library{
Book []books; //创建图书数组对象
int amount; //存入图书的种类数
String f_Path; //当前图书库源文件路径
String f_Name; //当前图书库源文件名称
NormalComparator NC=new NormalComparator();
Scanner re=new Scanner(System.in);
Library() {
books = new Book[1000]; //定义图书数组长度为1000
this.amount=0;
}
//求长度
public int length(){
return this.amount;
}
//堆排序 :表头不参与排序
//将以low为根的子树调整成大顶堆,low、high是序列下界和上界
public void sift(int low, int high,int w) {
int i = low; //子树的根
int j = 2 * i ; //j为i结点的左孩子
Book temp = books[i];
while (j<high) { //沿较小值孩子结点向下筛选
if (j<high-1 && (NC.compare(books[j].attribute[w],books[j + 1].attribute[w]))<=0) { //有右孩子
j++; //数组元素比较,j为左右孩子的较大者
}
if (NC.compare(temp.attribute[w],books[j].attribute[w]) <= 0) { //若父母结点值较小
books[i] = books[j]; //孩子结点中的较大值上移
i = j;
j = 2 * i ;
} else {
j = high + 1; //退出循环
}
}
books[i] = temp; //当前子树的原根值调整后的位置
}
public void heapSort(int w) { // w 为关键字属性对应编号
int n = this.amount; //元素数
Book temp;
for (int i = n/2;i>0;i--) { //创建堆
sift(i, n, w);
}
for (int i=n-1; i>1;i--) { //每趟将最大值交换到后面,再调整成堆
temp = books[1];
books[1] = books[i];
books[i] = temp;
sift(1, i, w);
}
}
//添加图书
public void addBook(Book a_book) { //添加图书
if(amount==books.length){
Book[] B = books;
books = new Book[amount+500]; //扩大可存储书目数量,每次扩容500
for(int j=0;j<B.length;j++){
books[j]=B[j];
}
}
books[amount]=a_book;
amount++;
}
//删除图书
public void del_Book(int i){
if(i>0&&i<this.amount){
this.books[i].toString();
this.books[i]=this.books[--this.amount];
}
else
System.out.println("使用了非法索引!");
}
//修改图书
public void alter_Book(int i,int w){ //修改books[i]图书的第w个属性值
if(i>0&&i<this.amount){
this.books[i].attribute[w]=re.next();
}
else
System.out.println("使用了非法索引!");
}
//查找图书(完整关键字查找) :表头不参与查找
/*
*先排序 查找所在位置
*有序记录下的,折半查找:精确查找需要输入完整的属性值
*/
public int binarySearch(String key,int w){
if(length()>0){
int low=1,high=length()-1;
while(low<=high){
int n=(low+high)/2;
if((NC.compare(books[n].attribute[w],key))==0)
return n;
else if((NC.compare(books[n].attribute[w],key))>0) //关键字值小于中间值
high=n-1;
else
low=n+1;
}
}
return -1; //查找不成功
}
//递归形式
public int binarySearch(int low,int high,String key,int w){
while(low<=high){
int n=(low+high)/2;
if((NC.compare(books[n].attribute[w],key))==0)
return n;
else if((NC.compare(books[n].attribute[w],key))>0)
return binarySearch(low,n-1,key,w);
else
return binarySearch(n+1,high,key,w);
}
return -1; //查找不成功
}
//查找图书(部分关键字查找) :表头不参与
//顺序查找 :返回位置
public int seqSearch(String key,int w){
int i=0,n=length();
while((books[n].attribute[w].indexOf(key))==-1){
i++;
}
if(i<n) return i;
else return -1;
}
//顺序查找所有 :返回一个Lirary类型
public Library seqAllSearch(String key,int w){
Library lib=new Library();
lib.addBook(this.books[0]); //将表头插入
int i=0,n=length();
while(i<n){
if((books[i].attribute[w].indexOf(key))!=-1){
lib.addBook(this.books[i]);
}
i++;
}
return lib;
}
//保存到源文件
public void save_File(){
try{
Object_io io=new Object_io();
io.object_io_out(this,new File(this.f_Path.concat(this.f_Name)));
}
catch(Exception e){
System.out.print(e);
}
}
//另存为新文件
public void save_As_File(Library lib,String str){
try{
Object_io io=new Object_io();
str=str.concat(".csv");
str=lib.f_Path.concat(str);
io.object_io_out(lib,new File(str));
}
catch(Exception e){
System.out.print(e);
}
}
}
Menu.java
import java.io.*;
import java.util.*;
public class Menu{
Scanner re=new Scanner(System.in);
Library lib;
boolean label;
public Menu(Library lib){
this.lib=lib;
this.label=true;
while(this.label){
this.first_Meun();
}
}
//主菜单
public void first_Meun(){
System.out.println("\t==============================");
System.out.println("\t---------[ 主菜单 ]-----------");
System.out.println("\t[1] 插入图书:");
System.out.println("\t[2] 删除图书:");
System.out.println("\t[3] 修改图书:");
System.out.println("\t[4] 查询图书:");
System.out.println("\t[5] 排序图书:");
System.out.println("\t[6] 保存至源文件:");
System.out.println("\t[7] 另存为新文件:");
System.out.println("\t[0] 退出系统:");
System.out.println("\t-----------------------------");
System.out.print("\t请输入选项编号:");
int ser=re.nextInt();
switch(ser){
case 1:this.insert_Book();break;
case 2:this.del_Book();break;
case 3:this.amend_Book();break;
case 4:this.search_Menu();break;
case 5:this.sort();break;
case 6:this.lib.save_File();break;
case 7:System.out.print("请输入新的文件名:");
String str=re.next();
this.lib.save_As_File(this.lib,str);
break;
case 0: System.out.println("请选择:[1]保存并退出;[2]直接退出;[3]取消退出");
int xu=re.nextInt();
if(xu==1) { this.lib.save_File();this.label=false;break; }
if(xu==2) { this.label=false;break; }
if(xu==3) { break; }
else break;
default:System.out.println("\t----无此选项!------");break;
}
}
//查找子菜单
public void search_Menu(){
System.out.println("\t==============================");
System.out.println("\t----------[ 查找 ]------------");
System.out.println("\t[1] 精确查找:");
System.out.println("\t[2] 模糊查找:");
System.out.println("\t-----------------------------");
System.out.print("\t请输入选项编号:");
int ser=re.nextInt();
this.attribute_Meun();
switch(ser){
case 1:this.search_True();break;
case 2:this.search_Flase();break;
default:System.out.println("\t----无此选项!------");break;
}
}
//属性菜单
public void attribute_Meun(){
System.out.println("\t==============================");
System.out.println("\t-----[ attribute_Meun ]-------");
System.out.println("\t ***属性**** **编号**\n");
System.out.println("\t *本季征订号 0");
System.out.println("\t *分册 1");
System.out.println("\t *出版社 2");
System.out.println("\t *ISBN 3");
System.out.println("\t *书名 4");
System.out.println("\t *著作者 5");
System.out.println("\t *适用分级 6");
System.out.println("\t *价格 7");
System.out.println("\t *出版年月 8");
System.out.println("\t *社内分类 9");
System.out.println("\t *中图法分类 10");
System.out.println("\t *学科分类编码 11");
System.out.println("\t *学科分类1 12");
System.out.println("\t *学科分类2 13");
System.out.println("\t-----------------------------");
}
//插入图书
public void insert_Book(){
String []str=new String[this.lib.books[0].attribute.length];
this.attribute_Meun();
System.out.println("请依次输入对应的属性值:");
for(int i=0;i<str.length;i++){
str[i]=re.next();
}
Book book=new Book(str);
this.lib.addBook(book);
}
//删除
public void del_Book(){
System.out.println("请输入要删除图书所在的位置:");
int i=re.nextInt();
this.lib.books[i].ruleToString();
this.lib.del_Book(i);
System.out.println("已删除!");
}
//修改
public void amend_Book(){
System.out.println("请输入要修改图书所在的位置:");
int i=re.nextInt();
int p=1;;
System.out.println(this.lib.books[i].toString());
this.attribute_Meun();
while(p>=0&&p<this.lib.books[i].amount){
System.out.println("请输入要修改的属性,对应的编号;输入-1 退出修改:");
p=re.nextInt();
if(p!=-1){
System.out.println("请输入修改后的值:");
this.lib.books[i].attribute[p]=re.next();
}
}
System.out.println("已修改为:");
this.lib.books[i].ruleToString();
}
//查询
//精确
public void search_True(){
System.out.println("请输入要查询的属性编号:");
int w=re.nextInt();
System.out.println("请输入要查询的属性值:");
String str=re.next();
this.lib.heapSort(w);
Library we=new Library(); //查询结果保存到临时图书库
we.f_Path=this.lib.f_Path; //设置默认路径
we.addBook(this.lib.books[0]); //将表头添加进去
NormalComparator NC=new NormalComparator();
int mark=this.lib.binarySearch(str,w);
int high=mark++,low=mark--;
if(mark==-1){
System.out.println("未找到");
}
else{
we.addBook(this.lib.books[mark]);
while(low>0&&(NC.compare(this.lib.books[low].attribute[w],str))==0)
we.addBook(this.lib.books[low--]);
while(high<this.lib.amount&&(NC.compare(this.lib.books[high].attribute[w],str))==0)
we.addBook(this.lib.books[high++]);
}
str=str.concat("_".concat(Integer.toString(we.amount)));
str="查找结果_".concat(str);
lib.save_As_File(we,str);
System.out.println("查询结果,已保存到文件;文件名为:"+str);
}
//模糊
public void search_Flase(){
System.out.println("请输入要查询的属性编号:");
int w=re.nextInt();
System.out.println("请输入要查询的属性值:");
String str=re.next();
Library we=this.lib.seqAllSearch(str,w);
we.f_Path=this.lib.f_Path;
str=str.concat("_".concat(Integer.toString(we.amount)));
str="查找结果_".concat(str);
lib.save_As_File(we,str);
System.out.println("查询结果,已保存到文件;文件名为:"+str);
}
//排序
public void sort(){
this.attribute_Meun();
System.out.println("请输入作为排序条件的属性编号:");
int w=re.nextInt();
this.lib.heapSort(w);
String str=this.lib.books[0].attribute[w];
str=str.concat("_".concat(Integer.toString(this.lib.amount)));
str="排序结果_".concat(str);
this.lib.save_As_File(this.lib,str);
System.out.println("查询结果,已保存到文件;文件名为:"+str);
}
}
Object_io.java
import java.io.*;
public class Object_io //对象流类
{
int DB_Limit=-1; //测试所用数据量
void object_io_out(Library lib,File file) throws Exception //向文件写入
{
FileWriter outOne = new FileWriter(file);
BufferedWriter outTwo=new BufferedWriter(outOne);
for(int i=0;i<lib.amount;i++){
String[] s=lib.books[i].attribute;
int j=0;
String str=s[j++];
for(;j<s.length;j++){
str=str.concat(",");
str=str.concat(s[j]); //将指定字符串连接到此字符串的结尾。
}
outTwo.write(str); //写入一行
outTwo.newLine(); //写入换行
}
outTwo.close();
outOne.close();
}
void object_io_in(Library lib,File file) throws Exception //从文件读出
{
FileReader inOne = new FileReader(file);
BufferedReader inTwo=new BufferedReader(inOne);
String strLine = null;
int x=0; //读出的数据条数
while((strLine = inTwo.readLine())!=null) //逐行读取
{
String item[]=strLine.split(",",14); //分离每行数据,根据给定正则表达式的匹配拆分此字符串。
if(x==0) Book.amount=item.length; //将表头属性数量存入
if(item.length==14){
Book book=new Book(item);
lib.addBook(book);
x++;
}
if(this.DB_Limit!=-1&&x>this.DB_Limit) //判断是否存在数据上限要求
break;
}
System.out.println("读取到的数据为"+x+"条;(包括表头)");
inOne.close();
inTwo.close();
}
}
NormalComparator.java
import java.util.Comparator;
/*
*Collator 类执行区分语言环境的 String 比较。使用此类可为自然语言文本构建搜索和排序例程。
*Collator 是一个抽象基类。其子类实现具体的整理策略。
*Java 平台目前提供了 RuleBasedCollator 子类,它适用于很多种语言。
*还可以创建其他子类,以处理更多的专门需要。
*与其他区分语言环境的类一样,可以使用静态工厂方法 getInstance 来为给定的语言环境获得适当的 Collator 对象。
*如果需要理解特定整理策略的细节或者需要修改策略,只需查看 Collator 的子类即可。
*下面的示例显示了如何使用针对默认语言环境的 Collator 比较两个字符串。
*
*
*/
import java.text.RuleBasedCollator;
import java.text.Collator;
import java.util.Locale;
public class NormalComparator implements Comparator<Object> {
/*
*RuleBasedCollator 为 Collator 的子类
*/
RuleBasedCollator collator = (RuleBasedCollator)Collator.getInstance(Locale.CHINA);//public static final Locale CHINA 指定中国的语言环境
/*
*比较用来排序的两个参数。根据第一个参数小于、等于或大于第二个参数分别返回负整数、零或正整数。
*/
public int compare(Object o1, Object o2) {
return collator.compare(o1.toString(), o2.toString());
}
}
Date_s.java
import java.util.Date;//导入日期类
import java.text.SimpleDateFormat;//导入简单的日期格式类
public class Date_s{
public static String h_Date(){ //静态方法
long startTime = System.currentTimeMillis();//获取当前时间(以毫秒为单位)
Date time=new Date(startTime);//创建日期对象;Date t=new Date(long ms)
String pattern="yyyy/MM/dd E HH:mm";//创建字符型日期格式模板
SimpleDateFormat SDF=new SimpleDateFormat(pattern);//创建简单日期格式;以模板为参数
String timePattern=SDF.format(time);
return timePattern;
}
}
Main.java
/*
*主菜单
*/
import java.io.*;
import java.util.*;
public class Main{
public static void main(String []args) throws Exception {
Scanner re=new Scanner(System.in);
System.out.println("\n\n-------------------------欢迎来到图书查询系统------------------------\n");
System.out.println(" "+Date_s.h_Date()+" \n");
System.out.println(" 注意:在使用过程中,请保证系统正常退出;否则可能会出现数据丢失! \n");
System.out.println("\n 注意:本次为测试过程;请输入合适的测试数据量(1--6万) \n");
System.out.println(" \t\t谢谢配合! \n");
System.out.println(" 您可以进入系统了 \n\n");
System.out.print("请输入测试所用数据量:");
int max_data=re.nextInt();
Library lib=new Library();
Object_io io=new Object_io();
io.DB_Limit=max_data;
lib.f_Path="Access\\Object\\"; //当前图书库源文件路径
lib.f_Name="2019春教材书目数据_(源).csv"; //当前图书库源文件名称
File file=new File(lib.f_Path.concat(lib.f_Name));
io.object_io_in(lib,file);
Menu m=new Menu(lib);
}
}
资源链接:
Github:here
百度网盘:https://pan.baidu.com/s/1akeCc9VDpskhXKw1pFNQHg
提取码:c4di