建立词索引表——程序源码:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<ctype.h>
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
typedef int Boolean;
#define MaxBookNum 1000 // 假设只对 1000 本书建立词索引表
#define MaxKeyNum 2500 // 索引表的最大容量
#define MaxLineLen 500 // 书目串的最大长度
#define MaxWordNum 10 // 词表的最大容量
#define MaxWordLen 100 // 关键词的最大长度
typedef struct {
char* ch; // 若是非空串, 则按串长分配存储区, 否则 ch 为 NULL
int length; // 串长度
}HString;
typedef struct {
char* item[MaxWordNum]; // 字符串的数组
int last; // 词表的长度
}WordListType; // 词表类型(顺序表)
typedef int ElemType; // 定义链表的数据元素类型为整型(书号类型)
typedef struct LNode {
ElemType data[3]; // 书号(三位数字)
struct LNode *next; // 指向下一个书号
}*Link,*LinkList;
typedef struct {
HString key; // 关键词
LinkList bnolist; // 存放书号索引的链表
}IdxTermType; // 索引项类型
typedef struct {
IdxTermType item[MaxKeyNum + 1];
int last;
}IdxListType; // 索引表类型(有序表)
//主要变量
char* buf; // 书目串缓冲区
char c[MaxLineLen];
int BookNo[3]; // 书号
char * No[]={"and","of","if","the","to","many","more"}; // 常用词表
WordListType wdlist; // 词表
IdxListType idxlist; // 索引表
Status StrAssign(HString &T, char* chars) {
int i;
char *c;
if(T.ch)
free(T.ch); // 释放 T 原有的空间
for(i=0, c=chars; c!='\0'; i++,c++)
printf("%c", c); // 求 chars 的长度 i
if(!i){
T.ch = NULL;
T.length = 0;
}
else {
if(!(T.ch = (char*)malloc(i*sizeof(char))))
return OVERFLOW;
T.length = i;
for(i=0; i<T.length; i++)
T.ch[i] = chars[i];
T.ch[i]='\0';
}
return OK;
}// StrAssign
int StrCompare(HString S, HString T){
int i;
for(i=0; i<S.length && i<T.length; i++)
if(S.ch[i] != T.ch[i])
return S.ch[i] - T.ch[i];
return S.length - T.length;
}// StrCompare
void StrCopy(HString &S,HString &T){
int i;
if(T.ch==NULL){S.ch=NULL;S.length=0;}
else{
for(i=0;i<T.length;i++)
S.ch[i]=T.ch[i];
S.ch[i]='\0';
S.length=T.length;
}
}// StrCopy
void GetWord(int i, HString &wd){
// char* p;
// p = *(wdlist.item + i); // 取词表中第 i 个字符串
// StrAssign(wd, p); // 生成关键字字符串
char *t=&(*wdlist.item[i]);
int n;
for(n=0;*t!='\0';n++)t++;
wd.length=n;
for(n=0;n<wd.length;n++)
wd.ch[n]=wdlist.item[i][n];
wd.ch[n]='\0';
}// GetWord
int Locate(IdxListType &idxlist, HString wd, Boolean &b) {
int i, m;
for(i = idxlist.last - 1; (m = StrCompare(idxlist.item[i].key, wd))>0; i--);
if(m == 0) { // 找到
b = TRUE;
return i;
}
else {
b = FALSE;
return i+1;
}
}// Locate
Status InitList(LinkList &L) {
int i;
if(!(L=(Link)malloc(sizeof(LNode))))
return OVERFLOW;
for(i=0; i<3; i++)
if(!(L->data[i] = (int)malloc(sizeof(int))))
return OVERFLOW;
L->next=NULL;
return OK;
}// InitList
void InsertNewKey(IdxListType &idxlist,int i,HString &wd){
int j;
for(j = idxlist.last-1; j>=i; j--) { // 后移索引项
StrCopy(idxlist.item[j+1].key,idxlist.item[j].key);
idxlist.item[j+1].bnolist = idxlist.item[j].bnolist;
}
// 插入新的索引项
StrCopy(idxlist.item[i].key, wd); // 串赋值
InitList(idxlist.item[i].bnolist); // 初始化书号索引表为空表
idxlist.last ++;
}// InsertNewKey
Status MakeNode(Link &t,ElemType e[]){
int i;
if(!(t = (Link)malloc(sizeof(LNode))))
return OVERFLOW;
else for(i=0;i<3;i++)
t->data[i]=e[i];
t->next=NULL;
return OK;
}// MakeNode
Status Appand(LinkList &L,Link s){
Link q = L;
if(!s)
return ERROR;
while(q->next)
q=q->next;
q->next=s;
return OK;
}// Appand
Status InsertBook(IdxListType &idxlist, int i, int bno[]) {
Link p;
if(!MakeNode(p, bno))
return ERROR; // 分配失败
Appand(idxlist.item[i].bnolist, p); // 插入新的书号索引
return OK;
}// InsertBook
void Init_HString(HString &wd){
wd.ch=(char *)malloc(MaxWordLen*sizeof(char));
for(int e=0; e<MaxWordLen; e++)
wd.ch[e]='\0';
wd.length=0;
}
Status InsIdxList(IdxListType &idxlist, int bno[]) {
int i, j, b;
HString wd;
Init_HString(wd);
for(i=0; i<wdlist.last; i++){
GetWord(i, wd);
j = Locate(idxlist, wd, b);
if(!b)
InsertNewKey(idxlist, j, wd); // 插入新的索引项
if(!InsertBook(idxlist, j, bno)) // 插入书号索引
return OVERFLOW;
}
return OK;
}// InsertIdxList
Status GetLine(FILE* f){
int i;
buf = c;
if(!feof(f)){
for(i=0; (c[i]=fgetc(f))!=EOF&&c[i]!='\n'&&i<MaxLineLen; i++);
c[i]='\0';
return OK;
}
else return ERROR;
}
void InitWordList(WordListType &wdlist){
int i,j;
for(i=0;i<MaxWordNum;i++){
wdlist.item[i] = (char *)malloc(MaxWordLen*sizeof(char));
for(j=0; j<MaxWordLen; j++)
wdlist.item[i][j]='\0';
}
wdlist.last=0;
}
Status IsKeyWord(char *wd){
int i;
for(i=0; No[i]!=NULL; i++)
if(!strcmp(No[i],wd))
return FALSE;
return TRUE;
}
void ExtractKeyWord(int BookNo[3]) {
int i = 0,j,k;
char chars[MaxWordLen];
while(*buf!=' '){
BookNo[i] = *buf - '0';
buf++;
i++;
}
InitWordList(wdlist);
int m=0;
for(i=0; *buf!='\0'&&wdlist.last<MaxWordNum;i++){
while(*buf==' ')
buf++;
for(j=0; *buf!=' '&&*buf!='\0'&&*(&(*buf))!='\n'; j++){
//if(isSupper(*buf))
chars[j] = tolower(*buf);
//else
// chars[j] = *buf;
buf++;
}
chars[j]='\0';
if(IsKeyWord(chars)){
for(k=0;k<j;k++)
wdlist.item[m][k] = chars[k];
m++;
wdlist.last++;
}
}
}
void PutText(FILE* g,IdxListType idxlist){
int i,j;
for(i=0; i<idxlist.last; i++){
fprintf(g,"%-20s ",idxlist.item[i].key.ch);
Link t=idxlist.item[i].bnolist->next;
while(t){
for(j=0;j<3;j++)
fprintf(g,"%d",t->data[j]);
fprintf(g,",");
t=t->next;
}
fprintf(g,"\n");
}
}
void InitIdxList(IdxListType &idxlist){
int i;
for(i=0; i<MaxKeyNum; i++){
Init_HString(idxlist.item[i].key);
}
InitList(idxlist.item[0].bnolist);
idxlist.last=0;
}
void main() { // 主函数
FILE *f, *g;
if(f = fopen("c:\\BookInfo.txt", "r"))
if(g = fopen("c:\\BookIdx.txt", "w"))
remove("c:\\BookIdx.txt");
if(g = fopen("c:\\BookIdx.txt", "w")) {
InitIdxList(idxlist); // 初始化索引表 idxlist 为空表
while(!feof(f)) {
GetLine(f); // 从文件 f 读入一个书目信息到 buf
ExtractKeyWord(BookNo); // 从 buf 提取关键词到词表, 书号导入 BookNo;
InsIdxList(idxlist, BookNo); // 将书号为 BookNo 的关键词插入索引表
}
PutText(g, idxlist); // 将生成的索引表 idxlist 输出到文件 g
}
fclose(g);
fclose(f);
}// main
示例输入 BookInfo.txt
005 Computer Data Structures
010 Introduction to Data Structures
023 Fundamentals of Data Structures
034 The Design and Analysis of Computer Algorithms
050 Introduction to Numerical Analysis
067 Numerical Analysis
示例输出 BookIdx.txt
algorithms 034,
analysis 034,050,067,
computer 005,034,
data 005,010,023,
design 034,
fundamentals 023,
introduction 010,050,
numerical 050,067,
structures 005,010,023,