zoukankan      html  css  js  c++  java
  • 数据结构4.2_串操作应用举例_建立词索引表

    信息检索是计算机应用的重要领域之一。

    举个例子图书馆书名检索系统;

    一般来讲通过书名关键词检索读者感兴趣的书是很重要的。

    因为读者一般不知道自己感兴趣的书的全名, 可能会凭印象提供一些关键词。

    那么检索系统就要求能够根据读者提供的关键词,显示所有含有该关键词的书目;

     

    1、从书名文件中读取一个书名串;

    2、从书名串中提取所有关键词到词表中;

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

    4、还有一个判断是否为关键词的机制,创建一个常用词表(an、a、of、the),如果从书名提取出的词不与常用词表中任意词相等,即为关键词;

    5、再索引表中查询关键词可能出现以下情况:

      1)索引表中已有此关键词的索引项,只要在该项中插入书号索引即可;

      2)需在索引表中插入词关键词的索引项,插入应按照词典有序原则进行;

     

    首先设定数据结构:

    词表是一个线性表,因为一本书名只有若干个关键词,其数量有限,则采用顺序存储结构即可。每个词都是一个字符串。

    索引表是一个有序表,在生成过程中需要频繁进行插入操作;索引表也为了查找用,为了提高查找效率,应采用顺序存储结构;

    索引表中每个索引项包含两个内容:其一是关键词;其二是书号索引;

      关键词:索引表是常驻机构,采用堆分配存储表示的串类型;

      书号索引:书号索引在索引表的生成过程中逐个插入,且不同关键词的书号索引个数不等,甚至可能相差很多,宜采用链表结构的线性表;

     

    首先定义一下数据结构和基本操作:

     1 #define MaxBookNum  1000     //假设只对1000本书建立索引表
     2 #define MaxKeyNum    2500     //索引表的最大长度
     3 #define MaxLineLen     500      //书名串最大长度
     4 #define MaxWordNum  10        //词表最大容量
     5 
     6 typedef struct{
     7     char *item[];    //字符串的数组
     8     int last;            //词表长度
     9 }WordListType;   //词表类型
    10 
    11 
    12 typedef struct{
    13     HString  key;       //关键词
    14     LinkList  bnolist;  //存放书号索引的链表
    15 }IdxTermType;  //定义索引项
    16 
    17 typedef int ElemType;   //定义链表的数据元素类型为整型
    18 
    19 typedef struct{
    20     IdxTermType  item[MaxKeyNum+1];
    21     int    last;
    22 }IdxListType    //索引表类型
    23 
    24 char * buf;  //书名串缓冲区
    25 WordListType  wdlist;  //词表
    26 
    27 //初始化操作,置索引表为空表,且在idxlist.item[0]设一空串
    28 void InitIdxList(IdxListType &idxlist);
    29 
    30 //从文件f读入一个书目到书目串缓冲区buf
    31 void GetLine(FILE f)
    32 
    33 //从buf中提取书名关键词到词表wdlist,书号存入bno
    34 void ExtractKeyWord(ElemType &bno)
    35 
    36 
    37 //将书号为bno的书名关键词按词典顺序插入索引表idxlist
    38 Status InsIdxList(IdxListType &idxlist,  ElemType bno)
    39 
    40 //将生成的索引表idxlist输出到文件g中
    41 void PutText(FILE g, IdxListType idxlist)

    这个词表用来把书目(书名)串,拆解成一个个词,存放到词表中。这里是将其作为一个缓冲区存在;

    插入书号索引表的函数中首先要检索词表中的词是否为关键词,是关键词的话再插入;

     

    这里先建立一个主函数:

     1 void main() {
     2     if(f=openf("BookInfo.txt","r")) 
     3         if(g=openf("BookIdx.txt","w")){
     4             InitIdxList(idxlist); //初始化索引表idxlist为空表
     5             while(!feof(f)){
     6                 GetLine(f); //从文件f中读入一个书目信息到buf
     7                 ExtractKeyWord(BookNo); //从buf提取关键词到词表,书号存入BookNo中
     8                 InsIdxList(idxlist, BookNo); //将书号为BookNo的关键词插入索引表
     9             }
    10             PutText(g, idxlist); //将生成的索引表idxlist输出到文件g 
    11         }
    12 }

    为实现上述操作,要先把InsIdxList实现:

     1 //用wd返回wdlist词表中的第i个关键词
     2 void GetWord(int i, HString &wd)
     3 
     4 //在索引表idxlist中查询是否存在与wd相等的关键词。
     5 //若存在,则返回其在索引表中的位置,且b取值TRUE;否则返回插入位置,且b取值FALSE;
     6 int Locate(IdxListType idxlist, HString wd, Boolean b)
     7 
     8 
     9 //在索引表idxlist的第i项插入新关键词wd,并初始化书号索引的链表为空 
    10 void InserNewKey();
    11 
    12 //在索引表idxlist的第i项插入书号为bno索引
    13 Status InsertBook();
    14 
    15 
    16 Status InsIdxList(IdxListType &idxlist, int bno){
    17     for(i=0; i<wdlist.list; ++i){
    18         GetWord(i,wd);
    19         j=Locate(idxlist,wd,b);
    20         if(!b) InserNewKey(idxlist, j, wd);   //插入新的索引项
    21         if(!InsertBook(idxlist,j,bno)) return OVERFLOW;   //插入书号索引
    22     }
    23     return OK;
    24 }
     1 void GetWord(int i, HString &wd){
     2     p=*(wdlist.item+i);  //取词表中第i个字符串
     3     StrAssign(wd,p);     //生成关键词字符串
     4 }
     5 
     6 
     7 
     8 int Locate(IdxListType &idxlist, HString wd, Boolean &b){
     9     for(i=idxlist.last-1; m=StrCompare(idxlist.item[i].key,wd)>0; --i);
    10     if(m==0) {b=TRUE; return i;}   //找到
    11     else{b=FALSE; return i+1;}
    12 }
    13 
    14 
    15 
    16 void InserNewKey(int i, StrType wd){
    17     for(j=idxlist.last-1;j>=i;--j)   //后移索引项
    18         idxlist.item[j+1]=idxlist.item[j];
    19     StrCopy(idxlist.item[i],wd);           //串赋值
    20     InitIdxList(idxlist.item[i].bnolist);  //初始化书号索引表为空表
    21     ++idxlist.last;
    22 }
    23 
    24 
    25 
    26 Status InsertBook(IdxListType &idxlist, int i, int bno){
    27     if(!MakeNode(p,bno)) return ERROR;   //分配失败
    28     Appand(idxlist.item[i].bnolist, p);    //插入新的书号索引
    29     return OK;
    30 }
  • 相关阅读:
    CF961E Tufurama 主席树
    [BZOJ3638 && BZOJ3272]带修区间不相交最大K子段和(线段树模拟费用流)
    [BZOJ5294][BJOI2018]二进制(线段树)
    [BZOJ5293][BJOI2018]求和(倍增)
    [BZOJ5306][HAOI2018]染色(容斥+FFT)
    [BZOJ5303][HAOI2018]反色游戏(Tarjan)
    [CF1053C]Putting Boxes Together(线段树)
    整体二分
    JSOI2018R2题解
    LCT维护子树信息
  • 原文地址:https://www.cnblogs.com/grooovvve/p/10398317.html
Copyright © 2011-2022 走看看