信息检索实验报告.docx
《信息检索实验报告.docx》由会员分享,可在线阅读,更多相关《信息检索实验报告.docx(17页珍藏版)》请在冰豆网上搜索。
信息检索实验报告
信管11班
吕双武(01083088)
熊炎波(01083094)
2004-6-12
第一单元文本处理与倒排文档的建立
实验目的:
通过用高级语言编程实现倒排文档组织,深刻理解倒排文档的结构和组成,掌握自动抽词标引、建立倒排文档的基本原理和实现方法。
实验内容:
(一)系统功能
建立文献信息条目的顺排文档;对标题字段、文摘或全文字段进行自动抽词标引;建立倒排文档组织。
(二)处理方法与思想
根据文献中词频、词性与词的区分能力之间的关系,具有好的区分能力的词应是中等词频有实际意义的词,根据这一思想去掉停用词,对文本进行词干化处理。
然后根据一定的关键词赋权方法进行自动标引和抽词,生成K-D文件和倒排文档。
(三)算法流程与数据结构
1、从磁盘中读入一篇文献
2、对文献文本进行预处理:
词汇分析
删除停用词
词干处理
选择标引词
建立概念等级关系
3、对选出的标引词及其地址和记录号进行输出并存储在磁盘空间中,生成标引词表wordlist.txt文件
4、对检索入口词进行规范化处理,通过屏幕输入检索词进行检索,并验证倒排文档的生成
(四)源程序
以下采用c程序设计语言实现上述算法
#include
#defineMAX_LENGTH6
#defineMAX_COUNT1000
#defineSTOPLIST_COUNT20
charxx[50][80];
intmaxline=0;/*theTotalLineOfThed1.txt*/
typedefstructnode{
charword[20];
charnum[10];
introw;
intcol;
}WNODE;
WNODEwordList[MAX_COUNT];
char*stopList[]={"a","an","and","are","as","at","be","by","for","from","in","is","of","on","or","our","the","to","with","we"};
intSearchWord(char*str){
inti=0;
for(;iif(strcmp(stopList[i],str)==0)return1;return0;}intReadWord(char*document){FILE*fp;inti=0;char*p;if((fp=fopen(document,"r"))==NULL)return1;while(fgets(xx[i],80,fp)!=NULL){p=strchr(xx[i],'\n');if(p)*p=0;i++;}maxline=i;fclose(fp);return0;}voidWord(char*docu_num){clrscr();inti,j,k,m,n,ll,h=0,t=0,r=0,flag;charyy[20];for(i=0;ill=strlen(xx[i]);//printf("%d\n",ll);//for(j=0;jk=n=0;for(j=0;j//if(isalpha(xx[i][j]))k++;if(isalpha(xx[i][j])){flag=1;yy[n++]=xx[i][j];}else{yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];//wordList[h].word=yy;for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}voidWriteWord(){FILE*fp;inti;clrscr();fp=fopen("WordList.txt","a");for(i=0;iif(strlen(wordList[i].word)){fprintf(fp,"%s\t",wordList[i].word);fprintf(fp,"%s\t",wordList[i].num);fprintf(fp,"%d\t",wordList[i].row);fprintf(fp,"%d\n",wordList[i].col);}}fclose(fp);}voidmain(){clrscr();FILE*fp;chardocument[10],num[10];printf("CopyRightByLvshuagnwu");printf("\n");printf("Enterthedocument-Filename:\n");scanf("%s",document);while(strcmp(document,"end")){printf("Enterthedocumentnumber(3wei):\n");scanf("%s",num);if(ReadWord(document)){printf("Cann'tOpenFile:%s!\n\007",document);return;}Word(num);WriteWord();printf("GetWordfrom%sSucceed!\n",document);printf("Enterthenextdocument-Filename:\n");scanf("%s",document);}}(五)算法效率与改进标引算法的比较次数为文献词汇量与停用词数量乘积,从磁盘空间读入文献和停用词表需要一定的时间,可以通过先比较词频生成临时文件,再与停用词表进行比较,同时扩大内存将停用词表直接放入内存,以以空间换时间的方式来提高标音和检索速度。 第二单元顺排文档检索算法的实现实验目的:通过用高级语言编程实现菊池敏典算法,深刻理解顺排文档的检索技术和算法设计原理。实验内容:(一)算法流程1、从提问文档中读取N个提问式,并进行语法检查2、生成提问展开表展开表的生成,根据算法描述的顺序方向划分为两大部分:前处理部分和后处理部分,设level(Ai)表示经过正向扫描以后Ai项在展开表中的层次值,AFD(Ai)表示检索项目词Ai的“匹配一致时转向地址”,NFD(Ai)表示检索项目词Ai的“匹配不一致时转向地址”:前处理部分,也叫正向扫描处理部分。按照逻辑提问式各项因子出现的先后顺序从左到右依次处理,设Ai为当前处理项.(1)扫描到检索词项,则把Ai的匹配比较条件、项目检索词Ai、检索类型标识符等有关信息置入展开表中响应位置,地址计数器加1并送到表中地址位,(2)扫描到“(”时,level=level+1扫描到“)”时,level=level-1(3)扫描到逻辑乘“*”运算符时,继续搜索下一检索项目词,把它的地址位的值置入AFD(Ai)中,并有level(Ai)level(4)扫描到逻辑加“+”,继续搜索下一个检索项目词,把它的地址位的值置入NFD(Ai)中,并有level(Ai)level(5)扫描到逻辑提问结束符“.”时,把检索最终“成功”标记置入最后一个检索项目词Ai的AFD(Ai)中,同时把检索最终“失败”标记置入NFD(Ai)后处理部分:也叫逆向扫描处理部分。逆向扫描从展开表的倒数第二项开始直到展开表的第一项处理完为止。(1)逆向扫描遇见NFD(Ai)栏目为空,则应向回搜索,依次判别各level(Ai)值。当满足条件level(Ai)>level(Aj),则立即停止向后搜索,并进行以下操作:NFD(Ai)NFD(Aj)(2)逆向扫描遇见AFD(Ai)为空时,同样应向回搜索,依次判别各项level(Aj)值。当满足条件level(Ai)>level(Aj)或者搜索到提问逻辑式中最后一个检索项目词时,进行以下操作:AFD(Ai)AFD(Aj)3、分析提问式Q=A+B*(C+D*(E+F))+G*HQ=01+02*(03+04*(05+06))+07*084、检索处理流程从顺排文档中依次读出一篇文献记录,然后与提问文档中所有的提问式进行匹配检索,如满足提问表达式所要求的条件,该文献记录就作为提问式的命中文献输出。系统需要对提问文档中各提问式分批进行处理,先从提问式文档中取N个提问式处理,当这N个提问式与所有数据库中文献记录匹配完毕后,再从提问式文档中取N个提问式重复以上处理过程,一直到提问式文档中数据处理完为止。(二)数据结构(1)检索词表结构检索词表是为了描述提问式中出现的提问检索词而设计的。因为在实际提问式处理过程中,提问检索词只是以其在检索词表中检索词号形式出现,而不是检索词本身。(2)展开表结构地址AFDNFD层次值检索词号属性项号比较部位比较条件有效位检索词项地址是指该行所在展开表中地址匹配成功时转向地址AFD,给出一旦在检索词与文献记录中标引词匹配成功时,下步应该处理的提问检索词在提问表中的地址。匹配不成功时转向地址NFD,给出一旦检索词与标引词匹配失败以后应该转向展开表中的地址。层次值给出层次计数器在完成展开表填写时的当前处理值。(3)标引词标识表结构是为了描述文献记录中各标引词特征而设立的,它的设立为提问文档与文献记录的匹配奠定了基础。标引此标识号有效值项目词标引词标识号是系统赋予从文献记录中抽出标引词的类编码,实际上是属性项号。有效位是指标引词在匹配中的有效长度。项目词是指具体的标引词(三)源程序以下采用c程序设计语言实现上述算法#includemain(){intb[20],a[20][4];inti,h,j,k,l,level;printf("inputquery:\n");i=0;do{scanf("%c",&b[i]);i++;}while(b[i]!='.');h=i;for(i=0;ia[i][0]=i+1;j=0;level=0;for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
if(strcmp(stopList[i],str)==0)return1;
return0;
}
intReadWord(char*document)
{
FILE*fp;
char*p;
if((fp=fopen(document,"r"))==NULL)return1;
while(fgets(xx[i],80,fp)!
=NULL){
p=strchr(xx[i],'\n');
if(p)*p=0;
i++;
maxline=i;
fclose(fp);
voidWord(char*docu_num){
clrscr();
inti,j,k,m,n,ll,h=0,t=0,r=0,flag;
charyy[20];
for(i=0;ill=strlen(xx[i]);//printf("%d\n",ll);//for(j=0;jk=n=0;for(j=0;j//if(isalpha(xx[i][j]))k++;if(isalpha(xx[i][j])){flag=1;yy[n++]=xx[i][j];}else{yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];//wordList[h].word=yy;for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}voidWriteWord(){FILE*fp;inti;clrscr();fp=fopen("WordList.txt","a");for(i=0;iif(strlen(wordList[i].word)){fprintf(fp,"%s\t",wordList[i].word);fprintf(fp,"%s\t",wordList[i].num);fprintf(fp,"%d\t",wordList[i].row);fprintf(fp,"%d\n",wordList[i].col);}}fclose(fp);}voidmain(){clrscr();FILE*fp;chardocument[10],num[10];printf("CopyRightByLvshuagnwu");printf("\n");printf("Enterthedocument-Filename:\n");scanf("%s",document);while(strcmp(document,"end")){printf("Enterthedocumentnumber(3wei):\n");scanf("%s",num);if(ReadWord(document)){printf("Cann'tOpenFile:%s!\n\007",document);return;}Word(num);WriteWord();printf("GetWordfrom%sSucceed!\n",document);printf("Enterthenextdocument-Filename:\n");scanf("%s",document);}}(五)算法效率与改进标引算法的比较次数为文献词汇量与停用词数量乘积,从磁盘空间读入文献和停用词表需要一定的时间,可以通过先比较词频生成临时文件,再与停用词表进行比较,同时扩大内存将停用词表直接放入内存,以以空间换时间的方式来提高标音和检索速度。 第二单元顺排文档检索算法的实现实验目的:通过用高级语言编程实现菊池敏典算法,深刻理解顺排文档的检索技术和算法设计原理。实验内容:(一)算法流程1、从提问文档中读取N个提问式,并进行语法检查2、生成提问展开表展开表的生成,根据算法描述的顺序方向划分为两大部分:前处理部分和后处理部分,设level(Ai)表示经过正向扫描以后Ai项在展开表中的层次值,AFD(Ai)表示检索项目词Ai的“匹配一致时转向地址”,NFD(Ai)表示检索项目词Ai的“匹配不一致时转向地址”:前处理部分,也叫正向扫描处理部分。按照逻辑提问式各项因子出现的先后顺序从左到右依次处理,设Ai为当前处理项.(1)扫描到检索词项,则把Ai的匹配比较条件、项目检索词Ai、检索类型标识符等有关信息置入展开表中响应位置,地址计数器加1并送到表中地址位,(2)扫描到“(”时,level=level+1扫描到“)”时,level=level-1(3)扫描到逻辑乘“*”运算符时,继续搜索下一检索项目词,把它的地址位的值置入AFD(Ai)中,并有level(Ai)level(4)扫描到逻辑加“+”,继续搜索下一个检索项目词,把它的地址位的值置入NFD(Ai)中,并有level(Ai)level(5)扫描到逻辑提问结束符“.”时,把检索最终“成功”标记置入最后一个检索项目词Ai的AFD(Ai)中,同时把检索最终“失败”标记置入NFD(Ai)后处理部分:也叫逆向扫描处理部分。逆向扫描从展开表的倒数第二项开始直到展开表的第一项处理完为止。(1)逆向扫描遇见NFD(Ai)栏目为空,则应向回搜索,依次判别各level(Ai)值。当满足条件level(Ai)>level(Aj),则立即停止向后搜索,并进行以下操作:NFD(Ai)NFD(Aj)(2)逆向扫描遇见AFD(Ai)为空时,同样应向回搜索,依次判别各项level(Aj)值。当满足条件level(Ai)>level(Aj)或者搜索到提问逻辑式中最后一个检索项目词时,进行以下操作:AFD(Ai)AFD(Aj)3、分析提问式Q=A+B*(C+D*(E+F))+G*HQ=01+02*(03+04*(05+06))+07*084、检索处理流程从顺排文档中依次读出一篇文献记录,然后与提问文档中所有的提问式进行匹配检索,如满足提问表达式所要求的条件,该文献记录就作为提问式的命中文献输出。系统需要对提问文档中各提问式分批进行处理,先从提问式文档中取N个提问式处理,当这N个提问式与所有数据库中文献记录匹配完毕后,再从提问式文档中取N个提问式重复以上处理过程,一直到提问式文档中数据处理完为止。(二)数据结构(1)检索词表结构检索词表是为了描述提问式中出现的提问检索词而设计的。因为在实际提问式处理过程中,提问检索词只是以其在检索词表中检索词号形式出现,而不是检索词本身。(2)展开表结构地址AFDNFD层次值检索词号属性项号比较部位比较条件有效位检索词项地址是指该行所在展开表中地址匹配成功时转向地址AFD,给出一旦在检索词与文献记录中标引词匹配成功时,下步应该处理的提问检索词在提问表中的地址。匹配不成功时转向地址NFD,给出一旦检索词与标引词匹配失败以后应该转向展开表中的地址。层次值给出层次计数器在完成展开表填写时的当前处理值。(3)标引词标识表结构是为了描述文献记录中各标引词特征而设立的,它的设立为提问文档与文献记录的匹配奠定了基础。标引此标识号有效值项目词标引词标识号是系统赋予从文献记录中抽出标引词的类编码,实际上是属性项号。有效位是指标引词在匹配中的有效长度。项目词是指具体的标引词(三)源程序以下采用c程序设计语言实现上述算法#includemain(){intb[20],a[20][4];inti,h,j,k,l,level;printf("inputquery:\n");i=0;do{scanf("%c",&b[i]);i++;}while(b[i]!='.');h=i;for(i=0;ia[i][0]=i+1;j=0;level=0;for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
ll=strlen(xx[i]);
//printf("%d\n",ll);
//for(j=0;jk=n=0;for(j=0;j//if(isalpha(xx[i][j]))k++;if(isalpha(xx[i][j])){flag=1;yy[n++]=xx[i][j];}else{yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];//wordList[h].word=yy;for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}voidWriteWord(){FILE*fp;inti;clrscr();fp=fopen("WordList.txt","a");for(i=0;iif(strlen(wordList[i].word)){fprintf(fp,"%s\t",wordList[i].word);fprintf(fp,"%s\t",wordList[i].num);fprintf(fp,"%d\t",wordList[i].row);fprintf(fp,"%d\n",wordList[i].col);}}fclose(fp);}voidmain(){clrscr();FILE*fp;chardocument[10],num[10];printf("CopyRightByLvshuagnwu");printf("\n");printf("Enterthedocument-Filename:\n");scanf("%s",document);while(strcmp(document,"end")){printf("Enterthedocumentnumber(3wei):\n");scanf("%s",num);if(ReadWord(document)){printf("Cann'tOpenFile:%s!\n\007",document);return;}Word(num);WriteWord();printf("GetWordfrom%sSucceed!\n",document);printf("Enterthenextdocument-Filename:\n");scanf("%s",document);}}(五)算法效率与改进标引算法的比较次数为文献词汇量与停用词数量乘积,从磁盘空间读入文献和停用词表需要一定的时间,可以通过先比较词频生成临时文件,再与停用词表进行比较,同时扩大内存将停用词表直接放入内存,以以空间换时间的方式来提高标音和检索速度。 第二单元顺排文档检索算法的实现实验目的:通过用高级语言编程实现菊池敏典算法,深刻理解顺排文档的检索技术和算法设计原理。实验内容:(一)算法流程1、从提问文档中读取N个提问式,并进行语法检查2、生成提问展开表展开表的生成,根据算法描述的顺序方向划分为两大部分:前处理部分和后处理部分,设level(Ai)表示经过正向扫描以后Ai项在展开表中的层次值,AFD(Ai)表示检索项目词Ai的“匹配一致时转向地址”,NFD(Ai)表示检索项目词Ai的“匹配不一致时转向地址”:前处理部分,也叫正向扫描处理部分。按照逻辑提问式各项因子出现的先后顺序从左到右依次处理,设Ai为当前处理项.(1)扫描到检索词项,则把Ai的匹配比较条件、项目检索词Ai、检索类型标识符等有关信息置入展开表中响应位置,地址计数器加1并送到表中地址位,(2)扫描到“(”时,level=level+1扫描到“)”时,level=level-1(3)扫描到逻辑乘“*”运算符时,继续搜索下一检索项目词,把它的地址位的值置入AFD(Ai)中,并有level(Ai)level(4)扫描到逻辑加“+”,继续搜索下一个检索项目词,把它的地址位的值置入NFD(Ai)中,并有level(Ai)level(5)扫描到逻辑提问结束符“.”时,把检索最终“成功”标记置入最后一个检索项目词Ai的AFD(Ai)中,同时把检索最终“失败”标记置入NFD(Ai)后处理部分:也叫逆向扫描处理部分。逆向扫描从展开表的倒数第二项开始直到展开表的第一项处理完为止。(1)逆向扫描遇见NFD(Ai)栏目为空,则应向回搜索,依次判别各level(Ai)值。当满足条件level(Ai)>level(Aj),则立即停止向后搜索,并进行以下操作:NFD(Ai)NFD(Aj)(2)逆向扫描遇见AFD(Ai)为空时,同样应向回搜索,依次判别各项level(Aj)值。当满足条件level(Ai)>level(Aj)或者搜索到提问逻辑式中最后一个检索项目词时,进行以下操作:AFD(Ai)AFD(Aj)3、分析提问式Q=A+B*(C+D*(E+F))+G*HQ=01+02*(03+04*(05+06))+07*084、检索处理流程从顺排文档中依次读出一篇文献记录,然后与提问文档中所有的提问式进行匹配检索,如满足提问表达式所要求的条件,该文献记录就作为提问式的命中文献输出。系统需要对提问文档中各提问式分批进行处理,先从提问式文档中取N个提问式处理,当这N个提问式与所有数据库中文献记录匹配完毕后,再从提问式文档中取N个提问式重复以上处理过程,一直到提问式文档中数据处理完为止。(二)数据结构(1)检索词表结构检索词表是为了描述提问式中出现的提问检索词而设计的。因为在实际提问式处理过程中,提问检索词只是以其在检索词表中检索词号形式出现,而不是检索词本身。(2)展开表结构地址AFDNFD层次值检索词号属性项号比较部位比较条件有效位检索词项地址是指该行所在展开表中地址匹配成功时转向地址AFD,给出一旦在检索词与文献记录中标引词匹配成功时,下步应该处理的提问检索词在提问表中的地址。匹配不成功时转向地址NFD,给出一旦检索词与标引词匹配失败以后应该转向展开表中的地址。层次值给出层次计数器在完成展开表填写时的当前处理值。(3)标引词标识表结构是为了描述文献记录中各标引词特征而设立的,它的设立为提问文档与文献记录的匹配奠定了基础。标引此标识号有效值项目词标引词标识号是系统赋予从文献记录中抽出标引词的类编码,实际上是属性项号。有效位是指标引词在匹配中的有效长度。项目词是指具体的标引词(三)源程序以下采用c程序设计语言实现上述算法#includemain(){intb[20],a[20][4];inti,h,j,k,l,level;printf("inputquery:\n");i=0;do{scanf("%c",&b[i]);i++;}while(b[i]!='.');h=i;for(i=0;ia[i][0]=i+1;j=0;level=0;for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
k=n=0;
for(j=0;j//if(isalpha(xx[i][j]))k++;if(isalpha(xx[i][j])){flag=1;yy[n++]=xx[i][j];}else{yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];//wordList[h].word=yy;for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}yy[n]='\0';if(flag){if(!SearchWord(yy)){for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];wordList[h].row=i;wordList[h].col=j-n;}h++;n=0;flag=0;k=0;}}}voidWriteWord(){FILE*fp;inti;clrscr();fp=fopen("WordList.txt","a");for(i=0;iif(strlen(wordList[i].word)){fprintf(fp,"%s\t",wordList[i].word);fprintf(fp,"%s\t",wordList[i].num);fprintf(fp,"%d\t",wordList[i].row);fprintf(fp,"%d\n",wordList[i].col);}}fclose(fp);}voidmain(){clrscr();FILE*fp;chardocument[10],num[10];printf("CopyRightByLvshuagnwu");printf("\n");printf("Enterthedocument-Filename:\n");scanf("%s",document);while(strcmp(document,"end")){printf("Enterthedocumentnumber(3wei):\n");scanf("%s",num);if(ReadWord(document)){printf("Cann'tOpenFile:%s!\n\007",document);return;}Word(num);WriteWord();printf("GetWordfrom%sSucceed!\n",document);printf("Enterthenextdocument-Filename:\n");scanf("%s",document);}}(五)算法效率与改进标引算法的比较次数为文献词汇量与停用词数量乘积,从磁盘空间读入文献和停用词表需要一定的时间,可以通过先比较词频生成临时文件,再与停用词表进行比较,同时扩大内存将停用词表直接放入内存,以以空间换时间的方式来提高标音和检索速度。 第二单元顺排文档检索算法的实现实验目的:通过用高级语言编程实现菊池敏典算法,深刻理解顺排文档的检索技术和算法设计原理。实验内容:(一)算法流程1、从提问文档中读取N个提问式,并进行语法检查2、生成提问展开表展开表的生成,根据算法描述的顺序方向划分为两大部分:前处理部分和后处理部分,设level(Ai)表示经过正向扫描以后Ai项在展开表中的层次值,AFD(Ai)表示检索项目词Ai的“匹配一致时转向地址”,NFD(Ai)表示检索项目词Ai的“匹配不一致时转向地址”:前处理部分,也叫正向扫描处理部分。按照逻辑提问式各项因子出现的先后顺序从左到右依次处理,设Ai为当前处理项.(1)扫描到检索词项,则把Ai的匹配比较条件、项目检索词Ai、检索类型标识符等有关信息置入展开表中响应位置,地址计数器加1并送到表中地址位,(2)扫描到“(”时,level=level+1扫描到“)”时,level=level-1(3)扫描到逻辑乘“*”运算符时,继续搜索下一检索项目词,把它的地址位的值置入AFD(Ai)中,并有level(Ai)level(4)扫描到逻辑加“+”,继续搜索下一个检索项目词,把它的地址位的值置入NFD(Ai)中,并有level(Ai)level(5)扫描到逻辑提问结束符“.”时,把检索最终“成功”标记置入最后一个检索项目词Ai的AFD(Ai)中,同时把检索最终“失败”标记置入NFD(Ai)后处理部分:也叫逆向扫描处理部分。逆向扫描从展开表的倒数第二项开始直到展开表的第一项处理完为止。(1)逆向扫描遇见NFD(Ai)栏目为空,则应向回搜索,依次判别各level(Ai)值。当满足条件level(Ai)>level(Aj),则立即停止向后搜索,并进行以下操作:NFD(Ai)NFD(Aj)(2)逆向扫描遇见AFD(Ai)为空时,同样应向回搜索,依次判别各项level(Aj)值。当满足条件level(Ai)>level(Aj)或者搜索到提问逻辑式中最后一个检索项目词时,进行以下操作:AFD(Ai)AFD(Aj)3、分析提问式Q=A+B*(C+D*(E+F))+G*HQ=01+02*(03+04*(05+06))+07*084、检索处理流程从顺排文档中依次读出一篇文献记录,然后与提问文档中所有的提问式进行匹配检索,如满足提问表达式所要求的条件,该文献记录就作为提问式的命中文献输出。系统需要对提问文档中各提问式分批进行处理,先从提问式文档中取N个提问式处理,当这N个提问式与所有数据库中文献记录匹配完毕后,再从提问式文档中取N个提问式重复以上处理过程,一直到提问式文档中数据处理完为止。(二)数据结构(1)检索词表结构检索词表是为了描述提问式中出现的提问检索词而设计的。因为在实际提问式处理过程中,提问检索词只是以其在检索词表中检索词号形式出现,而不是检索词本身。(2)展开表结构地址AFDNFD层次值检索词号属性项号比较部位比较条件有效位检索词项地址是指该行所在展开表中地址匹配成功时转向地址AFD,给出一旦在检索词与文献记录中标引词匹配成功时,下步应该处理的提问检索词在提问表中的地址。匹配不成功时转向地址NFD,给出一旦检索词与标引词匹配失败以后应该转向展开表中的地址。层次值给出层次计数器在完成展开表填写时的当前处理值。(3)标引词标识表结构是为了描述文献记录中各标引词特征而设立的,它的设立为提问文档与文献记录的匹配奠定了基础。标引此标识号有效值项目词标引词标识号是系统赋予从文献记录中抽出标引词的类编码,实际上是属性项号。有效位是指标引词在匹配中的有效长度。项目词是指具体的标引词(三)源程序以下采用c程序设计语言实现上述算法#includemain(){intb[20],a[20][4];inti,h,j,k,l,level;printf("inputquery:\n");i=0;do{scanf("%c",&b[i]);i++;}while(b[i]!='.');h=i;for(i=0;ia[i][0]=i+1;j=0;level=0;for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
//if(isalpha(xx[i][j]))k++;
if(isalpha(xx[i][j])){flag=1;yy[n++]=xx[i][j];}
else{
yy[n]='\0';
if(flag){
if(!
SearchWord(yy)){
for(t=0;t<=n;t++)wordList[h].word[t]=yy[t];
//wordList[h].word=yy;
for(r=0;r<=4;r++)wordList[h].num[r]=docu_num[r];
wordList[h].row=i;
wordList[h].col=j-n;
h++;
n=0;
flag=0;
k=0;
voidWriteWord()
inti;
fp=fopen("WordList.txt","a");
for(i=0;iif(strlen(wordList[i].word)){fprintf(fp,"%s\t",wordList[i].word);fprintf(fp,"%s\t",wordList[i].num);fprintf(fp,"%d\t",wordList[i].row);fprintf(fp,"%d\n",wordList[i].col);}}fclose(fp);}voidmain(){clrscr();FILE*fp;chardocument[10],num[10];printf("CopyRightByLvshuagnwu");printf("\n");printf("Enterthedocument-Filename:\n");scanf("%s",document);while(strcmp(document,"end")){printf("Enterthedocumentnumber(3wei):\n");scanf("%s",num);if(ReadWord(document)){printf("Cann'tOpenFile:%s!\n\007",document);return;}Word(num);WriteWord();printf("GetWordfrom%sSucceed!\n",document);printf("Enterthenextdocument-Filename:\n");scanf("%s",document);}}(五)算法效率与改进标引算法的比较次数为文献词汇量与停用词数量乘积,从磁盘空间读入文献和停用词表需要一定的时间,可以通过先比较词频生成临时文件,再与停用词表进行比较,同时扩大内存将停用词表直接放入内存,以以空间换时间的方式来提高标音和检索速度。 第二单元顺排文档检索算法的实现实验目的:通过用高级语言编程实现菊池敏典算法,深刻理解顺排文档的检索技术和算法设计原理。实验内容:(一)算法流程1、从提问文档中读取N个提问式,并进行语法检查2、生成提问展开表展开表的生成,根据算法描述的顺序方向划分为两大部分:前处理部分和后处理部分,设level(Ai)表示经过正向扫描以后Ai项在展开表中的层次值,AFD(Ai)表示检索项目词Ai的“匹配一致时转向地址”,NFD(Ai)表示检索项目词Ai的“匹配不一致时转向地址”:前处理部分,也叫正向扫描处理部分。按照逻辑提问式各项因子出现的先后顺序从左到右依次处理,设Ai为当前处理项.(1)扫描到检索词项,则把Ai的匹配比较条件、项目检索词Ai、检索类型标识符等有关信息置入展开表中响应位置,地址计数器加1并送到表中地址位,(2)扫描到“(”时,level=level+1扫描到“)”时,level=level-1(3)扫描到逻辑乘“*”运算符时,继续搜索下一检索项目词,把它的地址位的值置入AFD(Ai)中,并有level(Ai)level(4)扫描到逻辑加“+”,继续搜索下一个检索项目词,把它的地址位的值置入NFD(Ai)中,并有level(Ai)level(5)扫描到逻辑提问结束符“.”时,把检索最终“成功”标记置入最后一个检索项目词Ai的AFD(Ai)中,同时把检索最终“失败”标记置入NFD(Ai)后处理部分:也叫逆向扫描处理部分。逆向扫描从展开表的倒数第二项开始直到展开表的第一项处理完为止。(1)逆向扫描遇见NFD(Ai)栏目为空,则应向回搜索,依次判别各level(Ai)值。当满足条件level(Ai)>level(Aj),则立即停止向后搜索,并进行以下操作:NFD(Ai)NFD(Aj)(2)逆向扫描遇见AFD(Ai)为空时,同样应向回搜索,依次判别各项level(Aj)值。当满足条件level(Ai)>level(Aj)或者搜索到提问逻辑式中最后一个检索项目词时,进行以下操作:AFD(Ai)AFD(Aj)3、分析提问式Q=A+B*(C+D*(E+F))+G*HQ=01+02*(03+04*(05+06))+07*084、检索处理流程从顺排文档中依次读出一篇文献记录,然后与提问文档中所有的提问式进行匹配检索,如满足提问表达式所要求的条件,该文献记录就作为提问式的命中文献输出。系统需要对提问文档中各提问式分批进行处理,先从提问式文档中取N个提问式处理,当这N个提问式与所有数据库中文献记录匹配完毕后,再从提问式文档中取N个提问式重复以上处理过程,一直到提问式文档中数据处理完为止。(二)数据结构(1)检索词表结构检索词表是为了描述提问式中出现的提问检索词而设计的。因为在实际提问式处理过程中,提问检索词只是以其在检索词表中检索词号形式出现,而不是检索词本身。(2)展开表结构地址AFDNFD层次值检索词号属性项号比较部位比较条件有效位检索词项地址是指该行所在展开表中地址匹配成功时转向地址AFD,给出一旦在检索词与文献记录中标引词匹配成功时,下步应该处理的提问检索词在提问表中的地址。匹配不成功时转向地址NFD,给出一旦检索词与标引词匹配失败以后应该转向展开表中的地址。层次值给出层次计数器在完成展开表填写时的当前处理值。(3)标引词标识表结构是为了描述文献记录中各标引词特征而设立的,它的设立为提问文档与文献记录的匹配奠定了基础。标引此标识号有效值项目词标引词标识号是系统赋予从文献记录中抽出标引词的类编码,实际上是属性项号。有效位是指标引词在匹配中的有效长度。项目词是指具体的标引词(三)源程序以下采用c程序设计语言实现上述算法#includemain(){intb[20],a[20][4];inti,h,j,k,l,level;printf("inputquery:\n");i=0;do{scanf("%c",&b[i]);i++;}while(b[i]!='.');h=i;for(i=0;ia[i][0]=i+1;j=0;level=0;for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
if(strlen(wordList[i].word)){
fprintf(fp,"%s\t",wordList[i].word);
fprintf(fp,"%s\t",wordList[i].num);
fprintf(fp,"%d\t",wordList[i].row);
fprintf(fp,"%d\n",wordList[i].col);
voidmain()
chardocument[10],num[10];
printf("CopyRightByLvshuagnwu");
printf("\n");
printf("Enterthedocument-Filename:
\n");
scanf("%s",document);
while(strcmp(document,"end")){
printf("Enterthedocumentnumber(3wei):
scanf("%s",num);
if(ReadWord(document)){
printf("Cann'tOpenFile:
%s!
\n\007",document);
return;
Word(num);
WriteWord();
printf("GetWordfrom%sSucceed!
\n",document);
printf("Enterthenextdocument-Filename:
}}
(五)算法效率与改进
标引算法的比较次数为文献词汇量与停用词数量乘积,从磁盘空间读入文献和停用词表需要一定的时间,可以通过先比较词频生成临时文件,再与停用词表进行比较,同时扩大内存将停用词表直接放入内存,以以空间换时间的方式来提高标音和检索速度。
第二单元顺排文档检索算法的实现
通过用高级语言编程实现菊池敏典算法,深刻理解顺排文档的检索技术和算法设计原理。
(一)算法流程
1、从提问文档中读取N个提问式,并进行语法检查
2、生成提问展开表
展开表的生成,根据算法描述的顺序方向划分为两大部分:
前处理部分和后处理部分,
设level(Ai)表示经过正向扫描以后Ai项在展开表中的层次值,AFD(Ai)表示检索项目词Ai的“匹配一致时转向地址”,NFD(Ai)表示检索项目词Ai的“匹配不一致时转向地址”:
前处理部分,也叫正向扫描处理部分。
按照逻辑提问式各项因子出现的先后顺序从左到右依次处理,设Ai为当前处理项.
(1)扫描到检索词项,则把Ai的匹配比较条件、项目检索词Ai、检索类型标识符等有关信息置入展开表中响应位置,地址计数器加1并送到表中地址位,
(2)扫描到“(”时,level=level+1
扫描到“)”时,level=level-1
(3)扫描到逻辑乘“*”运算符时,继续搜索下一检索项目词,把它的地址位的值置入AFD(Ai)中,并有level(Ai)level
(4)扫描到逻辑加“+”,继续搜索下一个检索项目词,把它的地址位的值置入NFD(Ai)中,并有level(Ai)level
(5)扫描到逻辑提问结束符“.”时,把检索最终“成功”标记置入最后一个检索项目词Ai的AFD(Ai)中,同时把检索最终“失败”标记置入NFD(Ai)
后处理部分:
也叫逆向扫描处理部分。
逆向扫描从展开表的倒数第二项开始直到展开表的第一项处理完为止。
(1)逆向扫描遇见NFD(Ai)栏目为空,则应向回搜索,依次判别各level(Ai)值。
当满足条件level(Ai)>level(Aj),则立即停止向后搜索,并进行以下操作:
NFD(Ai)NFD(Aj)
(2)逆向扫描遇见AFD(Ai)为空时,同样应向回搜索,依次判别各项level(Aj)值。
当满足条件level(Ai)>level(Aj)或者搜索到提问逻辑式中最后一个检索项目词时,进行以下操作:
AFD(Ai)AFD(Aj)
3、分析提问式
Q=A+B*(C+D*(E+F))+G*H
Q=01+02*(03+04*(05+06))+07*08
4、检索处理流程
从顺排文档中依次读出一篇文献记录,然后与提问文档中所有的提问式进行匹配检索,如满足提问表达式所要求的条件,该文献记录就作为提问式的命中文献输出。
系统需要对提问文档中各提问式分批进行处理,先从提问式文档中取N个提问式处理,当这N个提问式与所有数据库中文献记录匹配完毕后,再从提问式文档中取N个提问式重复以上处理过程,一直到提问式文档中数据处理完为止。
(二)数据结构
(1)检索词表结构
检索词表是为了描述提问式中出现的提问检索词而设计的。
因为在实际提问式处理过程中,提问检索词只是以其在检索词表中检索词号形式出现,而不是检索词本身。
(2)展开表结构
地址
AFD
NFD
层次值
检索
词号
属性
项号
比较
部位
条件
有效位
词项
地址是指该行所在展开表中地址
匹配成功时转向地址AFD,给出一旦在检索词与文献记录中标引词匹配成功时,下步应该处理的提问检索词在提问表中的地址。
匹配不成功时转向地址NFD,给出一旦检索词与标引词匹配失败以后应该转向展开表中的地址。
层次值给出层次计数器在完成展开表填写时的当前处理值。
(3)标引词标识表结构
是为了描述文献记录中各标引词特征而设立的,它的设立为提问文档与文献记录的匹配奠定了基础。
标引此标识号
有效值
项目词
标引词标识号是系统赋予从文献记录中抽出标引词的类编码,实际上是属性项号。
有效位是指标引词在匹配中的有效长度。
项目词是指具体的标引词
(三)源程序
main()
{intb[20],a[20][4];
inti,h,j,k,l,level;
printf("inputquery:
i=0;
do{scanf("%c",&b[i]);i++;}
while(b[i]!
='.');
h=i;
for(i=0;ia[i][0]=i+1;j=0;level=0;for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
a[i][0]=i+1;
j=0;level=0;
for(i=0;i{if((b[i]>='A')&&(b[i]<='Z')){j++;a[j][4]=b[i];}if(b[i]=='+'){a[j][2]=a[j+1][0];a[j][3]=level;}if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}if(b[i]=='(')level+=1;if(b[i]==')')level-=1;if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}}for(j=l;j>0;j--){if(a[j-1][3]>a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[j][1];}if(a[j-1][3]==a[j][3]){if(a[j-1][1]!=0)a[j-1][2]=a[j][2];if(a[j-1][2]!=0)a[j-1][1]=a[l][1];}if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
{if((b[i]>='A')&&(b[i]<='Z'))
{j++;a[j][4]=b[i];}
if(b[i]=='+')
{a[j][2]=a[j+1][0];a[j][3]=level;}
if(b[j]=='*'){a[j][1]=a[j+1][0];a[j][3]=level;}
if(b[i]=='(')level+=1;
if(b[i]==')')level-=1;
if(b[i]=='.'){a[j][1]='Y';a[j][2]='N';l=j;}
for(j=l;j>0;j--)
{if(a[j-1][3]>a[j][3])
{if(a[j-1][1]!
=0)
a[j-1][2]=a[j][2];
if(a[j-1][2]!
a[j-1][1]=a[j][1];
if(a[j-1][3]==a[j][3])
a[j-1][1]=a[l][1];}
if(a[j-1][3]{if(a[j-1][1]!=0){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][2]=a[k][2];}}if(a[j-1][2]!=2){for(k=j;k<=l;k++){if(a[k][3]<=a[j-1][3])a[j-1][1]=a[k][1];}}}printf("addafdnfdlevelword\n");for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
{for(k=j;k<=l;k++)
{if(a[k][3]<=a[j-1][3])
a[j-1][2]=a[k][2];
=2)
a[j-1][1]=a[k][1];
}}}
printf("addafdnfdlevelword\n");
for(j=1;j{for(i=0;i<5;i++)printf("%d",&a[j][i]);printf("\n");}}}(四)算法改进算法的不足A.比较匹配策略花费的机时可观,比较次数m*nB.不同提问式中相同提问词重复的比较和匹配处理;C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。改进:对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。第三单元倒排文档检索算法的实现实验目的:通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。实验内容:(一)算法描述1、输入检索式,并进行语法检查,显示出错信息;2、将提问表达式转换为等价的逆波兰表达式形式(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;(3)原始提问表达式存放区,数据在该区从左到右读入处理;(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。3、将逆波兰表达式转换为检索指令表:顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。同时将该单元封闭起来,置入使用标记。将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入4、在倒排文档基础之上利用检索指令表进行检索处理;5、屏幕输出检索结果;(二)数据结构处理环节有以下三个环节构成:1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。第一个环节:输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。第二个环节:输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。检索指令的数据结构ON检索指令操作码,AD1第一操作数地址,AD2第二操作数地址,AD3第三操作数地址。输入指令存贮指令逻辑或操作指令逻辑乘操作指令逻辑非一型指令逻辑非二型指令终止操作指令临时工作数据存贮区第三环节:输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。倒排文档结构文献地址存贮工作单元区 (三)源程序以下采用c程序设计语言实现上述算法#include"stdio.h"#include"string.h"#include"conio.h"#definem0100voidmain(){charstr[m0];charexp[m0];charstack[m0];charyard[m0][m0];charindex[m0][mo]floatyard[m0],d;FILE*fp;charch,cc;inti,j,t,k,n,x,y,top=0;i=0;clrscr();printf("PleaseinputQueryString")printf("\n")do{i++;scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/}while(str[i]!='#'&&i!=m0);t=1;i=1;/*n=1;*/ch=str[i];i++;while(ch!='#')/*以下进行逆波兰转换*/{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/exp[t]=ch;t++;/*n++;*/}elseif(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/{top++;stack[top]=ch;}elseif(ch==')'){while(stack[top]!='('){exp[t]=stack[top];top--;t++;}top--;}elseif(ch=='+'||ch=='-'){while(top!=0&&stack[top]!='('){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}elseif(ch=='*'){while(stack[top]=='*'){exp[t]=stack[top];top--;t++;}top++;stack[top]=ch;}ch=str[i];i++;}while(top!=0){exp[t]=stack[top];t++;top--;}exp[t]='#';for(j=1;j<=t;j++)printf("%c",exp[j]);printf("\n")}/*从文件中分行读入文献记录*//*fp=fopen("index.dat");j=0for(i=0;i<100;i++){while(fp!='#'){fscanf(fp,"%c",&index[i][j]);j++;ch=index[i][j];y=1;top=0;for(k=1;k<=t;k++){if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')cc=exp[k];top++;{if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*//*yard[top][y]=i+1;y++;}else{switch(exp[k]){case'+':yard[top-1]=strcat(yard[top-1],yard[top]);break;case'-':yard[top-1]=str(yard[top],yard[top-1]);break;case'*':yard[top-1]=str(yard[top-1],yard[top]);break;top--;}}if(feof(fp))break;}fclose(fp);printf("TheRetrievalResultsare:");printf("\n");for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
{for(i=0;i<5;i++)
printf("%d",&a[j][i]);
(四)算法改进
算法的不足
A.比较匹配策略花费的机时可观,比较次数m*n
B.不同提问式中相同提问词重复的比较和匹配处理;
C.展开表采用固定长格式占用过多的内存空间,以及对一个提问式中提问词数量的限制;
D.标引词标识表中同一属性项号下的各检索词应该组织一下,以减少查询时间;
E.对否定的处理有一定的限制,不能处理逻辑非作用在子表达式上这种情况。
改进:
对于B的不足,通过增加一标识变量,来记录体温次出现的次数,只对第一次出现该提问词时进行比较,重复出现时不予比较。
对于E的不足,通过逆序算法进行逻辑非运算,实现对检索提问中否定的处理。
第三单元倒排文档检索算法的实现
通过用高级语言编程实现福岛算法,深刻理解倒排文档的检索技术和算法设计原理。
(一)算法描述
1、输入检索式,并进行语法检查,显示出错信息;
2、将提问表达式转换为等价的逆波兰表达式形式
(1)根据表达式的语法规则,给每一个算子赋上一个优先数,以决定在处理过程中它们进入算子保留栈的顺序;
(2)设立两个数据存贮区,一个是提问算子保留栈,另一个是形成的结果保留区,用于存放逆波兰表达式;
(3)原始提问表达式存放区,数据在该区从左到右读入处理;
(4)从原始提问式存贮区中读数据时,若遇到算项,逆波兰数据区计数器加1,并将算项存入;
(5)读入数据时,若遇见算子,则将当前所处理的算子项的优先数与算子保留栈栈顶中算子的优先数进行比较:
若其优先数大于栈顶算子的优先级,则将算子保留栈计数器加1,并将当前算子项存入算子保留栈中;
若其优先数不大于栈顶算子的优先级,并且当前项又不是括号,此时应将则将算子保留栈计数器减1,取出栈顶算子项,同时将逆波兰区计数器加1,并将其存入,再转向(5)
(6)若扫描中遇见左括号,则将算子计数器加1后存入算子保留栈中;
(7)遇见右括号,表示要对左右括号内所包括的子表达式进行运算。
将算子保留栈栈顶项依次退出栈中,并存放在逆波兰表达式存贮区中,直到栈顶元素项是左括号时,将两个配对括号抛弃为止。
(8)若遇见提问表达式结束标记时,则将算子保留栈栈顶元素项依次送入逆波兰表达式存贮区中。
3、将逆波兰表达式转换为检索指令表:
顺序扫描逆波兰输出区,在临时工作数据区中找出一个未使用单元,把该单元地址送入当前检索指令项第三操作数地址栏目中。
同时将该单元封闭起来,置入使用标记。
将检索词的地址置入第一操作数地址栏目,把当前检索指令项的操作数栏目内置入
4、在倒排文档基础之上利用检索指令表进行检索处理;
5、屏幕输出检索结果;
处理环节有以下三个环节构成:
1、把用户的提问逻辑式转换成与之在逻辑语义上等价的逆波兰表达式;
2、把形成的逆波兰表达式转换成利于系统内部检索处理的形式------检索指令结构形式;
3、利用已经形成的检索指令序列,在倒排文档上进行检索,将检索的命中文献记录等其它有关信息输出给用户。
第一个环节:
输入数据是提问表达式,输出的是加工处理后的逆波兰表达式。
参照算符优先级对照表与检索词与地址对照表定义提问式算子存贮区、逆波兰表达式输出区与提问式输出区。
第二个环节:
输入数据是逆波兰表达式,输出数据是与之等价的检索指令系列。
检索指令的数据结构
ON检索指令操作码,
AD1第一操作数地址,
AD2第二操作数地址,
AD3第三操作数地址。
输入指令
存贮指令
逻辑或操作指令
逻辑乘操作指令
逻辑非一型指令
逻辑非二型指令
终止操作指令
临时工作数据存贮区
第三环节:
输入信息是经过处理后的检索指令系列,输出数据是命中文献记录号集合。
倒排文档结构
文献地址存贮工作单元区
#include"stdio.h"
#include"string.h"
#include"conio.h"
#definem0100
voidmain(){
charstr[m0];
charexp[m0];
charstack[m0];
charyard[m0][m0];
charindex[m0][mo]
floatyard[m0],d;
charch,cc;
inti,j,t,k,n,x,y,top=0;
printf("PleaseinputQueryString")
printf("\n")
do
scanf("%c",&str[i]);/*读取提问表达式,并保存在字符型数组str[i]中*/
}while(str[i]!
='#'&&i!
=m0);
t=1;
i=1;
/*n=1;*/
ch=str[i];
while(ch!
='#')/*以下进行逆波兰转换*/
if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')
/*asp[n]=ch;*//*生成检索词表,算项保存在数组asp[k]中*/
exp[t]=ch;
t++;
/*n++;*/
else
if(ch=='(')/*生成算子栈,并判断优先级,符合条件的算子保存在数组stack[top]中,判断算子出栈,进入逆波兰输出区*/
top++;
stack[top]=ch;
if(ch==')')
while(stack[top]!
='(')
exp[t]=stack[top];
top--;
if(ch=='+'||ch=='-')
while(top!
=0&&stack[top]!
if(ch=='*')
while(stack[top]=='*')
exp[t]='#';
for(j=1;j<=t;j++)printf("%c",exp[j]);
printf("\n")}
/*从文件中分行读入文献记录*/
/*
fp=fopen("index.dat");
j=0
for(i=0;i<100;i++)
while(fp!
='#')
fscanf(fp,"%c",&index[i][j]);
j++;
ch=index[i][j];
y=1;
top=0;
for(k=1;k<=t;k++)
cc=exp[k];
if(strcmp(ch,cc)=0)/*算项集合与文献记录进行比较*/
/*yard[top][y]=i+1;
y++;
switch(exp[k])
case'+':
yard[top-1]=strcat(yard[top-1],yard[top]);break;
case'-':
yard[top-1]=str(yard[top],yard[top-1]);break;
case'*':
yard[top-1]=str(yard[top-1],yard[top]);break;
if(feof(fp))break;
printf("TheRetrievalResultsare:
");
for(x=1;x{i=yard[1][x];printf("%c",index[i]);}}(四)算法改进该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
i=yard[1][x];
printf("%c",index[i]);
该算法一般需要七个工作区,与检索提问式的形式有很大关系,可以通过改变检索式的构造形式,优化检索算项和算子的存储方式,以准波兰式的形式对检索算子与算项进行实时运算来节省空间和时间,进而提高检索效率。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1