数据结构-串操作应用之词索引表

为书库创建查询索引表

建立词索引表基本步骤:

  1、从书目文件中读入一个书目单。

  2、从书目单中提取所有关键字插入词表。

  3、对词表中的每一个关键字在索引表中进行查找并作相应的插入操作。

详细操作:

  1、为识别从书名串中分离出来的单词是否是关键字,需要一张常用词表。顺序扫描书目单,首先分离单词,然后查找常用词表,若不和表中任一词相等,则为关键字,插入临时存放关键字的词表中。

  2、在索引表中查询关键字时可能出现两种情况:其中一种是索引表上已经有此关键词的索引项,只要在该项中插入书号索引即可;其二是需要在索引表中插入此关键词的索引项,插入应按字典有序原则插入。

  3、首先定义存储的数据结构:词表为线性表,只存放一本书的书名中若干个关键字,其数量有限,采用顺序存储结构即可,其中每个词是一个字符串。索引表为有序表,虽是动态生成,在生成过程中需频繁进行插入操作,但考虑索引表主要为查找用,为了提高查找效率,采用顺序存储结构;表中每隔索引项包含两个内容:其一是关键词,因索引表为常驻内存,则考虑节省存储,采用堆分配存储表示的串类型;其二是书号索引,由于书号索引是在索引表生成过程中逐个插入,且不同关键词的书号索引个数不等,甚至可能相差很多,则宜采用链表结构的线性表。

代码实现部分:

ConcordanceList.cpp

  1 #include "ChainedList.h"
  2 #include "HeapString.h"
  3 
  4 #include <conio.h>
  5 
  6 #define  MaxBookNum      1000    // 假设只对1000本书建索引表
  7 #define  MaxKeyNum       2500    // 索引表的最大容量
  8 #define  MaxLineLen       500    // 书目串的最大长度
  9 #define  MaxWordNum        10    // 词表的最大容量
 10 #define  MaxWordLength     30    // 单词的最大长度
 11 
 12 typedef int Boolean;
 13 typedef int Status;
 14 
 15 typedef struct {
 16     char    item[MaxWordNum][MaxWordLength];  // 字符串的数组
 17     int     last;        // 词表的长度
 18 } WordListType;          // 词表类型(顺序表)
 19 
 20 typedef struct {
 21     HString   key;       // 关键词
 22     LinkList bnolist;   // 存放书号索引的链表
 23 } IdxTermType;           // 索引项类型
 24 
 25 typedef struct {
 26     IdxTermType  item[MaxKeyNum+1];
 27     int          last;
 28 } IdxListType;           // 索引表类型(有序表)
 29 
 30 //------ 基本操作 ------
 31 void InitIdxList(IdxListType &idxlist);
 32    // 初始化操作,置索引表idxlist为空表,即idxlist.last=0,
 33    // 且在idxlist.item[0]设一空串
 34 void GetLine(FILE *f);
 35    // 从文件f读入一个书目信息到书目串缓冲区buf
 36 Status ExtractKeyWord(char *Buffer, WordListType &w, int &bno);
 37    // 从buf中提取书名关键词到词表wdlist,书号存入bno
 38 Status InsertIdxList(IdxListType &idxlist, ElemType bno);  
 39    // 将书号为bno的书名关键词按词典顺序插入索引表idxlist
 40 Status PutText(FILE *g, IdxListType idxlist);           
 41    // 将生成的索引表idxlist输出到文件g
 42 void PrintFile(FILE *FileName);
 43 
 44 Status InsertIdxList(IdxListType &idxlist, int bno);
 45    // 索引表插入算法
 46 void GetWord(int i, HString &wd);                
 47    // 用wd返回词表wdlist中第i个关键词。
 48 int Locate(IdxListType &idxlist, HString wd, Boolean &b);
 49    // 在索引表idxlist中查询是否存在与wd相等的关键词。
 50    // 若存在,则返回其在索引表中的位置,
 51    // 且b取值TRUE;否则返回插入位置,且b取值FALSE
 52 void InsertNewKey(IdxListType &idxlist, int i, HString wd);
 53    // 在索引表idxlist的第i项上插入新关键词wd,
 54    // 并初始化书号索引的链表为空表
 55 Status InsertBook(IdxListType &idxlist, int i, int bno);
 56    // 在索引表idxlist的第i项中插入书号为bno的索引
 57 
 58 //------ 主要变量 ------
 59 char          buf[MaxLineLen];   // 书目串缓冲区
 60 WordListType  wdlist;    // 词表
 61 IdxListType   idxlist;   // 索引表
 62 
 63 //------ 主函数 ------
 64 int main(int argc, char* argv[]) { 
 65   FILE *f,*g;
 66   int BookNo;
 67   if ((f = fopen("BookInfo.txt", "r"))==NULL) {
 68     printf("ERROR in open BookInfo.txt!\n");
 69     exit(1);
 70   }
 71   if ((g = fopen ("BookIdx.txt", "w"))==NULL) {
 72     printf("ERROR in open BookIdx.txt!\n");
 73     exit(1);
 74   }
 75   printf("书目文件:\n");
 76   PrintFile(f);
 77   InitIdxList(idxlist);         // 初始化索引表idxlist为空表
 78   while (!feof (f)) {
 79     GetLine (f);                // 从文件f读入一个书目信息到buf
 80     ExtractKeyWord(buf,wdlist,BookNo);  
 81         // 从buf提取关键词到词表,书号存入BookNo
 82     InsertIdxList(idxlist, BookNo);  // 书号为BookNo的关键词插入索引表
 83   }
 84   PutText(g, idxlist);          // 将生成的索引表idxlist输出到文件g
 85   fclose(f);
 86   fclose(g);
 87   printf("对书目文件进行处理后的索引文件:\n");
 88   if ((g = fopen ("Algo0409BookIdx.txt", "r"))==NULL) {
 89     printf("ERROR in open BookIdx.txt!\n");
 90     exit(1);
 91   }
 92   PrintFile(g);
 93   fclose(g);
 94   printf("按任意键,结束 ......\n");
 95   getch();
 96   return 0;
 97 } // main
 98 
 99 Status InsertIdxList(IdxListType &idxlist,  int bno) { 
100   int i,j;
101   HString wd;
102   Boolean b;
103   for (i=0;  i<wdlist.last;  i++) {
104     GetWord(i, wd);   
105     j = Locate(idxlist, wd, b);
106     if (!b)
107       InsertNewKey(idxlist, j, wd);  //  插入新的索引项
108     InsertBook(idxlist, j, bno);     //  插入书号索引
109   }
110   return OK;
111 } // InsertIdxList
112 
113 void GetWord(int i,  HString &wd) {
114   char *p;
115   p = *(wdlist.item +i);  // 取词表中第i个字符串
116   StrAssign(wd, p);       // 生成关键字字符串
117 } // GetWord
118 
119 int Locate(IdxListType &idxlist, HString wd, Boolean &b) {
120   int i,m;
121   for (i = idxlist.last-1; 
122        ((m = StrCompare(idxlist.item[i].key, wd)) > 0);  --i);
123   if (m==0) { // 找到
124     b = TRUE;
125     return i;  
126   } else {  // 没找到
127     b = FALSE;
128     return i+1;
129   }         
130 } // Locate
131 
132 void InsertNewKey(IdxListType &idxlist, int i, HString wd) {
133   int j;
134   for (j=idxlist.last-1;  j>=i;  --j)  // 后移索引项
135     idxlist.item[j+1] = idxlist.item[j];
136   // 插入新的索引项
137   StrCopy(idxlist.item[i].key, wd);    // 串赋值
138   InitList(idxlist.item[i].bnolist);   // 初始化书号索引表为空表
139   ++idxlist.last;
140 } // InsertNewKey
141 
142 Status InsertBook(IdxListType &idxlist, int i, int bno) {
143   Link p;
144   if (!MakeNode (p, bno)) 
145     return OVERFLOW;                   // 分配失败
146   Append(idxlist.item[i].bnolist, p);  // 插入新的书号索引
147   return OK;
148 } // InsertBook
149 
150 //------ 基本操作 -------
151 void InitIdxList(IdxListType &idxlist) {
152   int i;
153   idxlist.last= 0;
154   for(i=0; i<MaxKeyNum+1; i++)
155     InitList(idxlist.item[i].bnolist);
156 }
157 
158 Status ExtractKeyWord(char* Buffer,WordListType &w,int &Num) {
159   int i=0, j=0, k=0;
160   bool Ignore;
161   char TempChar[30];
162   char IgnoreChar[7][10] = { "to","of","the","and","not","or","if" };
163   w.last=0;
164   while(*(Buffer+i)!= ' ') { TempChar[i]=*(Buffer+i);  i++; }
165   i++;
166   TempChar[i]= '\0';
167   Num=atoi(TempChar);
168   while(*(Buffer+i)!='\n' && *(Buffer+i)!='\0') { 
169     // 每个字符串末尾都有作为结束符'\n'
170     if(*(Buffer+i)!=' ') { // 若非空字符,则把当前字符加入新的字符串中
171       if(*(Buffer+i)>='A' && *(Buffer+i)<='Z')  // 大写字母转换为小写
172         *(Buffer+i)-='A'-'a';
173       w.item[j][k]=*(Buffer+i);
174       k++;  i++;
175     } else {               // 如果是空字符,这是则开始另一个字符串
176       Ignore=false;
177       w.item[j][k++]='\0';
178       for (int m=0; m<7; m++)
179         if(strcmp(w.item[j],IgnoreChar[m])==0) 
180           { Ignore=true;  break; }
181       if (!Ignore) { j++;  k=0;  i++;  w.last++; }
182       else { k=0;  i++; }
183     }
184   }
185   w.item[j][k++]='\0';     // 把最后一个字符串收尾
186   Ignore=false;
187   for (int m=0; m<7; m++)
188     if (strcmp(w.item[j],IgnoreChar[m])==0) 
189       { Ignore=true;  break; }
190   if (!Ignore) w.last++;   // 并把最大数加1
191   return OK;
192 }
193 
194 void GetLine(FILE *f) {
195   fgets(buf, MaxLineLen, f);  // buf是全局数组变量
196 }
197 
198 Status PutText(FILE *IdxFile, IdxListType MyIdx) { 
199   int i,j,k;
200   Link p;
201   for(i=0; i<MyIdx.last; i++) {
202     for(j=0; j<MyIdx.item[i].key.length; j++)
203       putc(*(MyIdx.item[i].key.ch+j ),IdxFile);
204     putc('\t',IdxFile);
205     if (MyIdx.item[i].key.length < 8) putc('\t',IdxFile);
206     p = MyIdx.item[i].bnolist.head;
207     for (k=0; k<MyIdx.item[i].bnolist.len; k++) {
208       p = p->next;
209       fprintf(IdxFile,"%03d",p->data);
210       putc(' ', IdxFile);
211     }
212     putc('\n',IdxFile);
213   }
214   return OK;
215 }
216     
217 void PrintFile(FILE *FileName) {  // 辅助函数
218   char ch;
219   rewind(FileName);
220   ch=getc(FileName);
221   while (ch!=EOF) {
222     putchar(ch);
223     ch=getc(FileName);
224   }
225   printf("\n");
226   rewind(FileName);
227 }

HeapString.h

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 
 5 typedef int Status;
 6 #define OK 1
 7 #define ERROR 0
 8 #define OVERFLOW -2
 9 
10 typedef struct{
11     char *ch;    //若是非空串,则按串长度分配存储区域,否则ch为NULL
12     int length;    //串的长度
13 }HString;
14 
15 /*生成一个其值等于等于串常量chars的串T*/
16 Status StrAssign(HString &T, char *chars){
17     if(T.ch)
18         free(T.ch);    //若串存储空间不为NULl 释放原有空间
19     int i = strlen(chars);    //获取chars长度
20     if(!i){
21         T.ch = NULL;    //串常量chars长度为0时串为空串长度0存储区间指向NULL
22         T.length = 0;
23     }
24     else{
25         T.ch = (char *)malloc(i * sizeof(char));    //申请空间
26         if(!T.ch)
27             exit(OVERFLOW);
28         for(int j = 0; j < i; j++)
29             T.ch[j] = chars[j];        //写入chars串
30         T.length = i;
31     }
32     return OK;
33 }
34 
35 /*由串S复制得到T*/
36 Status StrCopy(HString &T, HString S){
37     if(T.ch)
38         free(T.ch);
39     T.ch = (char*)malloc(S.length * sizeof(char));
40     if(!T.ch)
41         exit(OVERFLOW);
42     for(int j = 0; j < S.length; j++)
43         T.ch[j] = S.ch[j];    
44     T.length = S.length;
45     return OK;
46 }
47 /*若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0*/
48 int StrCompare(HString T, HString S){
49     for(int i = 0; i < S.length && i < T.length; i++)
50         if(S.ch[i] != T.ch[i])
51             return S.ch[i] - T.ch[i];
52     return S.length - T.length;
53 }

ChainedList.h

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 #define OK 1
 5 #define ERROR 0
 6 #define OVERFLOW -2
 7 #define TRUE 1
 8 #define FALSE 0
 9 
10 typedef int Status;
11 typedef int ElemType;
12 
13 typedef struct LNode{
14     ElemType data;
15     struct LNode *next;
16 }*Link, *Position;
17 typedef struct{
18     Link head, tail;
19     int len;
20 }LinkList;
21 
22 Status InitList(LinkList &L){
23     L.head = (Link)malloc(sizeof(LNode));
24     if(!L.head)
25         exit(OVERFLOW);
26     L.tail = L.head;
27     L.len = 0;
28     L.head->next = NULL;
29     return 0;
30 }
31 
32 Status MakeNode(Link &p,ElemType e){
33     p = (Link)malloc(sizeof(LNode));
34     if(!p)
35         exit(OVERFLOW);
36     p->data = e;
37     p->next = NULL;
38     return OK;
39 }
40 
41 Status Append(LinkList &L, Link S){
42     Link p;
43     L.tail->next = S;
44     p = S;
45     ++L.len;
46     while(p->next){
47         p = p->next;
48         ++L.len;
49     }
50     L.tail = p;
51     return OK;
52 }

 

转载于:https://www.cnblogs.com/ABook/p/5697014.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
题目采自 《数据结构题集》(c语言版)(严蔚敏`吴伟民)6.3 图书管理,最大的难度在于要求用B树对书号进行索引。 设计语言:C语言 编译环境: VC++6.0 里面包含完整的源程序和报告文档,程序为dos界面,有彩色菜单,对数据显示实现格化……本课程设计成绩为优秀。 源程序有注释,报告文档完全按要求,包括所用数据结构的描述与实现、算法的时空分析等都包括在内。 程序所能达到的功能 1图书采编入库(用B树对书号建立索引) 2清除库存 3图书借阅 4图书归还 5图书预约 6列出某著者全部著作名 7列出某种书的状态(包括图书基本信息和该书借者名单、 预约者名单) 8每次插入或删除一个关键字后以凹入显示B树的状态 9把一次会话过程中的全部人机对话记录入一个日志文件中 10在程序主界面显示当前系统时间 一、 需求分析 1. 书号和借阅证号、库存量、出版年份用整型示;书名用20位字符型数组,著者和借阅者姓名用30位字符型数组示;图书价格用浮点型示。图书入库时输入图书的书号、书名、著者、总量等完整信息,清除库存时输入图书书号,借阅和归还时输入书号和借阅者证号,姓名等信息,并记录系统时间为借书日期。 2. 借书和归还时显示图书的信息。插入、删除后用凹入显示以书号建立的B树状态。查看图书状态,以格显示图书的基本信息,借阅者名单和预约者名单。 ……………… 课程设计清单: base.h //全程常量、全局变量和公共函数等 btree.h //B树类型单元 library.h //书库类型单元 main.cpp //主程序 bookiofo.dat //图书信息文件 borrower.dat //借书者姓名文件 bespeaker.dat //预约者姓名文件 main.exe //编译得到的可执行文件 数据结构课程设计实验报告-图书管理.doc

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值