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


    为书库创建查询索引表

    建立词索引表基本步骤:

      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]= '';
    167   Num=atoi(TempChar);
    168   while(*(Buffer+i)!='
    ' && *(Buffer+i)!='') { 
    169     // 每个字符串末尾都有作为结束符'
    '
    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++]='';
    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++]='';     // 把最后一个字符串收尾
    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('	',IdxFile);
    205     if (MyIdx.item[i].key.length < 8) putc('	',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('
    ',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("
    ");
    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 }
  • 相关阅读:
    正则匹配 sql语句参数
    正则判断是不是移动端浏览
    .net 2.0 后台多线程
    Oracle 获取当天数据
    C# 图片转Base64
    Js FileReader图片加载
    KendoUI操作笔记
    Android Studio解析Json文件内容
    LitePal
    C#最基本的小说爬虫
  • 原文地址:https://www.cnblogs.com/ABook/p/5697014.html
Copyright © 2020-2023  润新知