为书库创建查询索引表
建立词索引表基本步骤:
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! "); 69 exit(1); 70 } 71 if ((g = fopen ("BookIdx.txt", "w"))==NULL) { 72 printf("ERROR in open BookIdx.txt! "); 73 exit(1); 74 } 75 printf("书目文件: "); 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("对书目文件进行处理后的索引文件: "); 88 if ((g = fopen ("Algo0409BookIdx.txt", "r"))==NULL) { 89 printf("ERROR in open BookIdx.txt! "); 90 exit(1); 91 } 92 PrintFile(g); 93 fclose(g); 94 printf("按任意键,结束 ...... "); 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]= '