自然语言理解课程实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一、中文分词
一、实验内容
用正向最大匹配法对文档进行中文分词,其中:
(1)wordlist.txt 词表文件
(2)pku_test.txt 未经过分词的文档文件
(3)pku_test_gold.txt 经过分词的文档文件
二、实验所采用的开发平台及语言工具
Visual C++ 6.0
三、实验的核心思想和算法描述
本实验的核心思想为正向最大匹配法,其算法描述如下
假设句子: , 某一词 ,m 为词典
中最长词的字数。
(1) 令 i=0,当前指针 pi 指向输入字串的初始位置,执行下面的操作:
(2) 计算当前指针 pi 到字串末端的字数(即未被切分字串的长度)n ,如果n=1,
转(4),结束算法。否则,令 m=词典中最长单词的字数,如果n (3) 从当前 pi 起取m 个汉字作为词 wi ,判断: (a) 如果 wi 确实是词典中的词,则在wi 后添加一个切分标志,转(c); (b) 如果 wi 不是词典中的词且 wi 的长度大于1,将wi 从右端去掉一个字,转(a)步;否则(wi 的长度等于1),则在wi 后添加一个切分标志,将wi 作为单字词添加到词典中,执行 (c)步; (c) 根据 wi 的长度修改指针 pi 的位置,如果 pi 指向字串末端,转(4), 否则, i=i+1,返回 (2); (4) 输出切分结果,结束分词程序。 四、系统主要模块流程、源代码 (1) 正向最大匹配算法 12n S c c c = 12i m w c c c = (2)原代码如下 // Dictionary.h #include #include #include using namespace std; class CDictionary { public: CDictionary(); //将词典文件读入并构造为一个哈希词典 ~CDictionary(); int FindWord(string w); //在哈希词典中查找词 private: string strtmp; //读取词典的每一行 string word; //保存每个词 string strword[55400]; }; //将词典文件读入并 CDictionary::CDictionary() { ifstream infile("wordlist.txt"); // 打开词典 if (!infile.is_open()) // 打开词典失败则退出程序 { cerr << "Unable to open input file: " << "wordlist.txt" << " -- bailing out!" << endl; exit(-1); } int i=0; while (getline(infile, strtmp)) // 读入词典的每一行并将其添加入哈希中 { strword[i++]=strtmp; } infile.close(); } CDictionary::~CDictionary(){} //在哈希词典中查找词,若找到,则返回,否则返回 int CDictionary::FindWord(string w) { int i=0; while ((strword[i]!=w) && (i<55400)) i++; if(i<55400) return 1; else return 0; } // 主程序main.cpp #include "Dictionary.h" #define MaxWordLength 14 // 最大词长为个字节(即个汉字) # define Separator " " // 词界标记 CDictionary WordDic; //初始化一个词典 //对字符串用最大匹配法(正向)处理 string SegmentSentence(string s1) { string s2 = ""; //用s2存放分词结果 string s3 = s1; int l = (int) s1.length(); // 取输入串长度 int m=0; while(!s3.empty()) { int len =(int) s3.length(); // 取输入串长度 if (len > MaxWordLength) // 如果输入串长度大于最大词长 { len = MaxWordLength; // 只在最大词长范围内进行处理 } string w = s3.substr(0, len); //(正向用)将输入串左边等于最大词长长度串取出作为候选词 int n = WordDic.FindWord(w); // 在词典中查找相应的词 while(len > 1 && n == 0) // 如果不是词 { int j=len-1; while(j>=0 && (unsigned char)w[j]<128) { j--; } if(j<1) { break; } len -= 1; // 从候选词右边减掉一个英文字符,将剩下的部分作为候选词 w = w.substr(0, len); //正向用 n = WordDic.FindWord(w); } s2 += w + Separator; // (正向用)将匹配得到的词连同词界标记加到输出串末尾 s3 = s1.substr(m=m+w.length(), s1.length()); //(正向用)从s1-w处开始 } return s2; } int main(int argc, char *argv[]) { string strtmp; //用于保存从语料库中读入的每一行