您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 房地产 > 中文分词程序实验报告
汉语分词程序实验报告一、程序功能描述:本程序每次处理时都用缓冲区的数据从头开始去存储语料库的链表中匹配一个最长的词语来输出,如若没有匹配到的词语则单独输出该首字。为了简化程序所以语料库和预备分词文章都统一采用ASCII码的编码方式,并且不允许文中出现英语单字节编码。别且本程序没有对未登录词和未声明数据结构格式进行处理,都按照普通汉字进行了分词,因此在最后的性能比较中这部分的准确率很差,但是在语料库有存储的部分中都是用最长匹配原则进行了分词,准确率还是达到了很高的水平。分词符采用//+空格的方式来标记分词。语料库的名字默认为:语料库.txt,打开方式为只读读取的文件名字默认为:resource.txt,打开方式为只读输出的文件名字默认为:result.txt,打开方式默认为追加的方式二、算法思路:(1)、从文件中读取语料库存储在内存中,组织成单链表的存储方式(2)、组织以首字的ASCII码为下标的哈希表指向语料库链表(3)、从文件中读满输入缓冲区,以缓冲区的首字的ASCII码做为下标从哈希表中查找首字相同的内存地址。(4)、从该地址开始逐条匹配,记录其中匹配最长的词语的长度和地址。写入文件中并写入分词符。(5)、读满缓冲区,若文件已经读取完毕则查看缓冲区是否用尽,若已经用完则执行第(6)步,否则重复(4)过程。(6)、释放申请的内存空间,程序结束。三、数据结构:typedefstructcoredict{//使用链表来存储语料库chardata[9];structcoredict*nextPtr;}CoreDict,*CoreDictPtr;CoreDictPtrtablePtr=NULL,tailPtr=NULL,newPtr;//指向语料库链表的头和尾CoreDictPtrHash[65536]={NULL};//一个以匹配词语的第一个字的ASCII码为下标的指向链表的哈希表intMatchLength=0;//在一个单词匹配过程中用来记录能够匹配到的最长的词语的长度CoreDictPtrMatchPtr=NULL;//在一个单词匹配过程中用来记录能够匹配到的最长的词语在链表中的地址四、函数功能:intIsEqual(char[],char[]);//判断两个汉字是否相等intLongMatch(char[],char[]);//voidread(char[],FILE*);//将读入缓冲区读满voidsetoff(char[],int);//将已经匹配好的词语从缓冲区中删除五、性能对比分析:程序性能描述:在语义的判别和歧义消除方法只是用最长匹配法来降低误差,因此这部分的性能提升不是很明显。本程序没有对未登录词和未声明数据结构格式进行处理,都按照普通汉字进行了分词,因此在最后的性能比较中这部分的准确率比较差,但是在语料库有存储的部分中都是用最长匹配原则进行了分词,准确率还是达到了很高的水平。另外由于语料库规模的限制以及为了程序简化着想在普通词汇的搭配,例如形容词的组合方面还有一些低频词的分词方面也有些不是很高效。现有成熟分词程序的情况和大致性能:经过十几年的研究,汉语自动分词技术取得了令人瞩目的成果,出现了一些实用的自动分词系统,如:北京航空航天大学的cDws分词系统、清华大学的SEG分词系统和sE(玎AG分词系统等,这些系统在分词的精确度(精度达到99%以上)和分词速度(速度达到千字,s)方面都具有相当的水平。六、程序性能提高方向:(1).要能识别一些常见的数据格式,例如年月日、电话号码等。(2).可以跳过一些乱码,例如一串乱字符串,还有数字串等。(3).增加判别字符类型的函数,用来判别英文字符、汉语字符、还有另外的字符(4).建立词语之间关联性的数据库,可以从语义方面,甚至语用方面来从逻辑上增加分词的准确性,以达到消除歧义的目的。要是程序能增加上述的功能准确度应该可以达到90%以上。七、源代码:#includestdio.htypedefstructcoredict{chardata[9];structcoredict*nextPtr;}CoreDict,*CoreDictPtr;CoreDictPtrtablePtr=NULL,tailPtr=NULL,newPtr;CoreDictPtrHash[65536]={NULL};intMatchLength=0;CoreDictPtrMatchPtr=NULL;intIsEqual(char[],char[]);//判断两个汉字是否相等intLongMatch(char[],char[]);voidread(char[],FILE*);voidsetoff(char[],int);main(){inti;chartemp[9],ch[3],pre[3]={};unsignedshort*p;FILE*fPtr,*rePtr;printf(读取语料库中...\n);if((fPtr=fopen(语料库.txt,r))==NULL){//语料库printf(temp.txt文件打开失败\n);gotoEND;}if((newPtr=(CoreDictPtr)malloc(sizeof(CoreDict)))!=NULL){newPtr-nextPtr=NULL;fscanf(fPtr,%s,newPtr-data);//printf(%s\n,newPtr-data);tablePtr=newPtr;tailPtr=newPtr;pre[0]=newPtr-data[0];pre[1]=newPtr-data[1];p=(unsignedshort*)pre;Hash[*p]=tailPtr;}elseprintf(动态内存申请失败\n);tailPtr-nextPtr=NULL;while(!feof(fPtr)){if((newPtr=(CoreDictPtr)malloc(sizeof(CoreDict)))!=NULL){newPtr-nextPtr=NULL;fscanf(fPtr,%s,newPtr-data);//printf(%s\n,newPtr-data);tailPtr-nextPtr=newPtr;tailPtr=newPtr;ch[0]=newPtr-data[0];ch[1]=newPtr-data[1];if(!IsEqual(ch,pre)){//当该项的首字与前一个词的首字不相同时建立一个新的映射p=(unsignedshort*)ch;Hash[*p]=tailPtr;}pre[0]=ch[0];pre[1]=ch[1];}elseprintf(动态内存申请失败\n);}printf(文件散列读取完毕\n);printf(正在进行词汇匹配和分词...(若该result.txt存在则会追加在该文本之后)\n);fclose(fPtr);if((fPtr=fopen(resource.txt,r))==NULL){//source.txtprintf(source.txt文件打开失败\n);gotoEND;}if((rePtr=fopen(result.txt,a+))==NULL){//result.txtprintf(result.txt文件打开失败\n);gotoEND;}//printf(\n输入#表示结束查找\n);//scanf(%s,temp);temp[0]='\0';read(temp,fPtr);//printf(temp=%s\n,temp);while(temp[0]!=EOF&&temp[0]!='\0'){p=(unsignedshort*)temp;newPtr=Hash[*p];MatchLength=0;MatchPtr=NULL;if(newPtr!=NULL){//printf(与查找项首字相同的有:\n);//printf(%s\n,newPtr-data);//printf(temp=%s\n,temp);i=LongMatch(temp,newPtr-data);if(iMatchLength){MatchLength=i;MatchPtr=newPtr;}newPtr=newPtr-nextPtr;while(newPtr!=NULL&&IsEqual(newPtr-data,temp)){//printf(%s\n,newPtr-data);i=LongMatch(temp,newPtr-data);if(iMatchLength){MatchLength=i;MatchPtr=newPtr;}newPtr=newPtr-nextPtr;}}//else//printf(没有与查找项首字相同的\n);if(MatchPtr==NULL){//printf(没有匹配项\n);fprintf(rePtr,%c%c//,temp[0],temp[1]);setoff(temp,2);}else{//printf(最长匹配项为:%s匹配长度为:%d,MatchPtr-data,MatchLength);fprintf(rePtr,%s//,MatchPtr-data);setoff(temp,MatchLength);}//对输入缓冲区进行处理//printf(\n输入#表示结束查找\n);//scanf(%s,temp);read(temp,fPtr);}fclose(fPtr);fclose(rePtr);printf(释放语料库内存...\n);while(tablePtr!=NULL){newPtr=tablePtr;tablePtr=tablePtr-nextPtr;free(newPtr);}printf(释放语料库内存成功\n);END:system(pause);return0;}intIsEqual(chara[],charb[]){inti,k=0;if(a[0]==b[0]&&a[1]==b[1]&&a[0]!='\0'&&a[1]!='\0')return1;elsereturn0;}intLongMatch(chartemp[],charcoredic[]){inti=0,length=0;for(i=0;coredic[i]!='\0';i+=2)if(IsEqual(&(temp[i]),&(coredic[i])))length+=2;elsebreak;if(coredic[i]!='\0')length=0;returnlength;}voidread(chartemp[],FILE*fPtr){chara,b;inti;for(i=0;i8;i+=2)if(temp[i]=='\0'){fscanf(fPtr,%c,&a);temp[i]=a;if(a!=EOF){fscanf(fPtr,%c,&b);temp[i+1]=b;}elsebreak;temp[i+2]='\0';}}voidsetoff(chartemp[],intoff){//缓冲区左移inti=0;charch;ch=temp[0];while(ch!='\0'&&ch!=EOF){if(i+off=9)break;temp[i]=temp[i+off];i++;}}
本文标题:中文分词程序实验报告
链接地址:https://www.777doc.com/doc-5825610 .html