图书索引程序.docx
《图书索引程序.docx》由会员分享,可在线阅读,更多相关《图书索引程序.docx(19页珍藏版)》请在冰豆网上搜索。
图书索引程序
图书索引程序
1.问题:
图书馆需要对图书信息生成索引表(如下),以便用户在输入关键词时能查询到相应的图书,下面介绍生成索引表的思路。
2.算法思路:
a)首先得准备书目文件与非关键词文件(如下)
书目文件
非关键词文件
b)依次从书目文件中读入每一行的信息(字符串),从该字符串中提取书号,以及关键词(需要参考非关键词文件判断哪些单词是关键词),有序插入关键词链表,并附上拥有该关键词的书号,直至书目文件读完。
3.数据描述:
a)非关键词——链表
b)关键词——嵌套链表
4.结构化设计:
5.补充:
a)程序中有对书号进行有序插入,即使书目信息无序也无关系
b)fgets函数说明:
每条书目信息长度不一,当终归有上限,对于非关键词也一样。
因此只能一次读入整条书目信息,但是从该字符串中提取书号和关键词也是实现难点。
c)使用该代码时记得要修改相应文件的位置信息,避免出错。
6.局限:
a)对于搜索功能,本程序的索引表没有从相应文件读入(懒),而是执行生成索引表功能去生成,在时间上增加了复杂度。
b)不能实现中文版的图书索引系统(实力有限,不懂)。
7.程序运行:
a):
生成索引表
b):
图书搜索
8.代码展示:
#include
#include
#include
#include
#definebookno_length3//书号长度统一为3,只适用于999本书
structbook_no//书号表的元素
{
char*book_number;//指向书号的指针
structbook_no*next;//指向下一个元素
};
structone_key//关键字表的元素
{
char*key;//指向关键字的指针
intkey_length;//关键字的长度
structbook_no*head;//指向拥有该关键字的书号表的开头
structone_key*next;//指向下一个元素
};
structtemptable//临时表,存储普通词表和书目信息文件每一行拥有的关键词
{
char*word;//指向单词的指针
intword_length;//单词的长度,长度相等才进行比较,提高效率
structtemptable*next;//下一个元素
};
structbook_information
{
charbook[100];
structbook_information*next;
};
main()
{
voidprint_all_key_table(structone_key*all_key);
voidsearch_book_information(structone_key*all_key);
voidwelcome();
voidwrite_all_key_table(structone_key*all_key);
structone_key*create_all_key_table();//创造有序关键词表
structone_key*all_key=NULL;//关键字表的开头,带头结点
welcome();
inti;
scanf("%d",&i);
while(i!
=1&&i!
=2)
{
printf("输入出错重新录入\n");
scanf("%d",&i);
}
switch(i)
{
case1:
all_key=create_all_key_table();
print_all_key_table(all_key);
write_all_key_table(all_key);
break;
case2:
all_key=create_all_key_table();
search_book_information(all_key);
}
}
voidwelcome()
{
printf("*******************************************************\n\n");
printf("欢迎来到图书索引系统!
!
\n\n");
printf("*******************************************************\n\n");
printf("1:
生成索引文件\n2:
查找图书\n");
printf("请选择功能:
");
}
structone_key*create_all_key_table()
{
structtemptable*create_nokey_temptable();//创造非关键词词表
structtemptable*create_key_temptable(charbuf[100],structtemptable*nokey_temptable);//创造关键词词表
char*book_no(charbuf[100]);//提取书名号,长度统一为3
FILE*p;//指向书目信息
structone_key*all_key=NULL;//关键字表的开头,带头结点
structone_key*m1=NULL,*n1=NULL;//m1为临时结点,n1判断是否有重复以及插入位置
charbuf[100];//代表书目信息文件的每一行,是个字符串
char*bno;//buf中的书目号
structbook_no*m2=NULL,*n2=NULL;//m2为临时结点,n2判断插入位置
structtemptable*key_temptable=NULL,*nokey_temptable=NULL,*t=NULL;//指向buf中的关键词以及指向非关键词的词表
//总关键表初始化,带有头结点
all_key=(structone_key*)malloc(sizeof(structone_key));
all_key->key=NULL;
all_key->head=NULL;
all_key->next=NULL;
if((p=fopen("E:
\\c语言\\C语言编程软件\\我的工作空间\\课本\\例题\\关键词索引系统\\book_information.txt","r"))==NULL)
{
printf("没有相应的书目文件,程序结束");
exit(0);
}
nokey_temptable=create_nokey_temptable();//建立非关键词词表,相关文件的非关键词有序
fgets(buf,100,p);
while(!
feof(p))
{
bno=book_no(buf);//提取书号
key_temptable=create_key_temptable(buf,nokey_temptable);//提取当前书目信息的关键词,需要非关键词词表对比
for(t=key_temptable->next;t!
=NULL;t=t->next)//将临时的关键词表插入以及书号做成总关键词表
{
for(n1=all_key->next;n1!
=NULL;n1=n1->next)
if(n1->key_length==t->word_length&&!
strcmp(n1->key,t->word))//若为新关键词,则最终结果为n1=NULL;
break;
if(n1==NULL)//当前的临时关键词为新关键词,生成新结点,插入结点,插入书号
{
m1=(structone_key*)malloc(sizeof(structone_key));
m1->key=t->word;
m1->key_length=t->word_length;
m1->next=NULL;
m1->head=(structbook_no*)malloc(sizeof(structbook_no));
m1->head->next=NULL;
//链表为空,直接插入
if(all_key->next==NULL)
all_key->next=m1;
else//链表不空,进行寻找新结点的前一个结点
{
n1=all_key->next;
if(strcmp(m1->key,n1->key)<0)//插入开头
{
m1->next=n1;
all_key->next=m1;
}
else//插入中间
for(;n1->next!
=NULL;n1=n1->next)
{
if((strcmp(m1->key,n1->key)>0)&&(strcmp(m1->key,n1->next->key)<0))
{
m1->next=n1->next;
n1->next=m1;
break;
}
}
if(n1->next==NULL)//插入末尾
n1->next=m1;
}
//插入书号,此时m1指向新结点
m2=(structbook_no*)malloc(sizeof(structbook_no));
m2->book_number=bno;
m2->next=NULL;
m1->head->next=m2;
}
else//不是新关键词,此时n1指向重复项对应的结点,有序插入书号
{
m2=(structbook_no*)malloc(sizeof(structbook_no));
m2->book_number=bno;
m2->next=NULL;
n2=n1->head->next;
if(strcmp(m2->book_number,n2->book_number)<0)//插入开头
{
m2->next=n1->head->next;
n1->head->next=m2;
}
else//插入中间
for(;n2->next!
=NULL;n2=n2->next)
{
if((strcmp(m2->book_number,n2->book_number)>0)&&(strcmp(m2->book_number,n2->next->book_number)<0))
{
m2->next=n2->next;
n2->next=m2;
break;
}
}
if(n2->next==NULL)//插入末尾
n2->next=m2;
}
}
fgets(buf,100,p);
}
fclose(p);
returnall_key;
}
structtemptable*create_nokey_temptable()
{
char*change(charc[10]);//去除字符串末尾的回车符
structtemptable*nokey_temptable=NULL;//非关键词链表头指针
structtemptable*p=NULL;//辅助链表的建立
FILE*f;//指向非关键词词表文件,文件内的非关键词有序
charc[10],*s=NULL;//代表每一行的非关键词
if((f=fopen("E:
\\c语言\\C语言编程软件\\我的工作空间\\课本\\例题\\关键词索引系统\\nokey_information.txt","r"))==NULL)
{
printf("没有相应的非关键词文件,程序结束");
exit(0);
}
nokey_temptable=(structtemptable*)malloc(sizeof(structtemptable));//用带有头结点的链表存储非关键词词表
p=nokey_temptable;
p->next=NULL;
fgets(c,10,f);//必须预先读一次,否则会导致最后一行被读取两次
while(!
feof(f))
{
s=change(c);//将数组末尾的回车符去除
//插入链表
p->next=(structtemptable*)malloc(sizeof(structtemptable));
p=p->next;
p->word=s;
p->word_length=strlen(p->word);
p->next=NULL;
fgets(c,10,f);
}
fclose(f);
returnnokey_temptable;
}
char*change(charc[10])//去除字符串末尾的回车符
{
intlength,i;
char*s;
for(length==0;;length++)//计算单词长度
if(c[length]=='\n')
break;
s=(char*)malloc(sizeof(char)*length+1);
for(i=0;is[i]=c[i];
s[i]='\0';
returns;
}
char*book_no(charbuf[100])
{
inti;
char*s=NULL;
s=(char*)malloc(sizeof(char)*(bookno_length+1));
for(i=0;is[i]=buf[i];
s[i]='\0';
returns;
}
structtemptable*create_key_temptable(charbuf[100],structtemptable*nokey_temptable)
{
structtemptable*key_temptable=NULL;//当前书目信息关键词头指针
structtemptable*p=NULL;//辅助链表的建立
structtemptable*q=NULL;//指向非关键词表,筛选关键词
inti,j;//代表单词起点和终点坐标
intk;//赋值存储单词
intword_length;//单词长度
intjudge;//代表目前单词是否为关键词
key_temptable=(structtemptable*)malloc(sizeof(structtemptable));//带有头结点的关键词词表
p=key_temptable;
p->next=NULL;
char*s=NULL;//存储单词
i=j=bookno_length+1;//指向书目信息第一个单词的开头
for(;buf[j]!
='\0';)
{
judge=1;//设置默认值,1表示是关键词,反之为0
for(;buf[j]!
=''&&buf[j]!
='\n';j++);//遇到单词的结束标志,提取单词,判断是否为关键词,并插入
word_length=j-i;//计算单词长度,单词终点坐标减去单词起点坐标
s=(char*)malloc(sizeof(char)*word_length+1);
for(k=0;ks[k]=tolower(buf[i+k]);//装换成小写字母
s[k]='\0';//字符串结束标志
for(q=nokey_temptable->next;q!
=NULL;q=q->next)//根据非关键词表判断是否为关键词
if(strlen(s)==q->word_length&&!
strcmp(s,q->word))//先进行长度比较,初步判断
{
judge=0;
break;
}
if(judge==1)//生成目前书目信息的关键词表
{
p->next=(structtemptable*)malloc(sizeof(structtemptable));
p=p->next;
p->word=s;
p->word_length=strlen(s);
p->next=NULL;
}
else
free(s);//非关键词释放其存储空间
i=j=j+1;//下一个单词的起点
}
returnkey_temptable;
}
voidprint_all_key_table(structone_key*all_key)
{
inti;
structone_key*p=NULL;
structbook_no*q=NULL;
printf("输入1显示所生成的索引表,其它则不显示:
");
scanf("%d",&i);
if(i==1)
for(p=all_key->next;p!
=NULL;p=p->next)
{
printf("%s",p->key);
for(q=p->head->next;q!
=NULL;q=q->next)
printf("%s",q->book_number);
printf("\n");
}
}
voidwrite_all_key_table(structone_key*all_key)
{
FILE*f=NULL;
structone_key*p=NULL;
structbook_no*q=NULL;
f=fopen("E:
\\c语言\\C语言编程软件\\我的工作空间\\课本\\例题\\关键词索引系统\\key_table.txt","w");
for(p=all_key->next;p!
=NULL;p=p->next)
{
fputs(p->key,f);
fputs("",f);
for(q=p->head->next;q!
=NULL;q=q->next)
{
fputs(q->book_number,f);
fputs("",f);
}
fputs("\n",f);
}
printf("索引文件名为key_table,所在目录与该源文件的相同,请查看");
}
voidsearch_book_information(structone_key*all_key)
{
char*get_key();//获取字符串关键词
structbook_information*create_book_table();//创建书目信息链表
structbook_information*book_table=NULL;
structone_key*p=NULL;//对关键词表进行搜索
structbook_no*bno=NULL;//指向关键词表中拥有用户查询的关键词的书号
char*s=NULL;//存储用户查询的关键词
structbook_information*q=NULL;//指向书目信息链表
inti;//进行书号比较
intjudge;//书号判断结果
s=get_key();
book_table=create_book_table();
printf("搜索结果如下:
\n");
for(p=all_key->next;p!
=NULL;p=p->next)
{
if(strcmp(p->key,s)==0)//拥有相应的关键词
{
for(bno=p->head->next;bno!
=NULL;bno=bno->next)//指向该关键词的书号
for(q=book_table->next;q!
=NULL;q=q->next)//指向书目信息链表的开头,进行穷搜索
{
judge=1;//初始值
for(i=0;iif(q->book[i]!
=bno->book_number[i])
{
judge=0;
break;
}
if(judge==1)
printf("%s",q->book);
}
}
}
}
char*get_key()
{
char*s=NULL,c[30];
inti;
printf("输入相应的关键字,长度不超过30:
");
scanf("%s",c);
s=(char*)malloc(sizeof(char)*(strlen(c)+1));
for(i=0;is[i]=c[i];
s[i]='\0';
returns;
}
structbook_information*create_book_table()
{
book_information*book_table=NULL,*p=NULL;//p辅助链表的建立
book_table=(structbook_information*)malloc(sizeof(structbook_information));
book_table->next=NULL;
p=book_table;
inti;//书目信息的赋值
charbuf[100];
FILE*f=NULL;
if((f=fopen("E:
\\c语言\\C语言编程软件\\我的工作空间\\课本\\例题\\关键词索引系统\\book_info