《自然语言处理导论》中文分词程序实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《自然语言处理导论》

中文分词实验报告

一、实验目的

了解中文分词意义

掌握中文分词的基本方法

二、实验环境

Win7 64位

DEV-C++编译器

三、实验设计

(一)分词策略

目前较为成熟的中文分词方法主要有:

1、词典正向最大匹配法

2、词典逆向最大匹配法

3、基于确定文法的分词法

4、基于统计的分词方法

一般认为,词典的逆向匹配法要优于正向匹配法。基于确定文法和基于统计的方法作为自然语言处理的两个流派,各有千秋。

我设计的是根据词典逆向最大匹配法,基本思路是:

1、将词典的每个词条读入内存,最长是4字词,最短是1字词;

2、从语料中读入一段(一行)文字,保存为字符串;

3、如果字符串长度大于4个中文字符,则取字符串最右边的4个中文字符,作

为候选词;否则取出整个字符串作为候选词;

4、在词典中查找这个候选词,如果查找失败,则去掉这个候选词的最左字,重

复这步进行查找,直到候选词为1个中文字符;

5、将候选词从字符串中取出、删除,回到第3步直到字符串为空;

6、回到第2步直到语料已读完。

(二)程序设计

查找算法:哈希表

汉字编码格式:UTF-8

程序流程图:

源代码:

#include

#include

#include

#include

#include

#include

#include

#include

#define MaxWordLength 12 // 最大词长字节(即4个汉字)

#define Separator " " // 词界标记

#define UTF8_CN_LEN 3 // 汉字的UTF-8编码为3字节

using namespace std;

using namespace __gnu_cxx;

namespace __gnu_cxx

{

template<> struct hash< std::string >

{

size_t operator()( const std::string& x ) const

{

return hash< const char* >()( x.c_str() );

}

};

}

hash_map wordhash; // 词典

//读入词典

void get_dict(void)

{

string strtmp; //读取词典的每一行

string word; //保存每个词

typedef pair sipair;

ifstream infile("CoreDict.txt.utf8");

if (!infile.is_open())

{

cerr << "Unable to open input file: " << "wordlexicon"

<< " -- bailing out!" << endl;

system("pause");

exit(-1);

}

while (getline(infile, strtmp)) // 读入词典的每一行并将其添加入哈希中{

istringstream istr(strtmp);

istr >> word; //读入每行第一个词

wordhash.insert(sipair(word, 1)); //插入到哈希中

}

infile.close();

}

//删除语料库中已有的分词空格,由本程序重新分词

string del_space(string s1)

{

int p1=0,p2=0;

int count;

string s2;

while (p2 < s1.length()){

//删除半角空格

if (s1[p2] == 32)

{

if (p2>p1)

s2 += s1.substr(p1,p2-p1);

p2++;

p1=p2;

}

else

{

p2++;

}

}

s2 += s1.substr(p1,p2-p1);

return s2;

}

//用词典做逆向最大匹配法分词

string dict_segment(string s1)

{

string s2 = ""; //用s2存放分词结果

while (!s1.empty()) {

int len = (int) s1.length(); // 取输入串长度

if (len > MaxWordLength) // 如果输入串长度大于最大词长

{

len = MaxWordLength; // 只在最大词长范围内进行处理

string w = s1.substr(s1.length() - len, len);

int n = (wordhash.find(w) != wordhash.end()); // 在词典中查找相应的词

while (len > UTF8_CN_LEN && n == 0) // 如果不是词

{

len -= UTF8_CN_LEN; // 从候选词左边减掉一个汉字,将剩下的部分作为候选词

w = s1.substr(s1.length() - len, len);

n = (wordhash.find(w) != wordhash.end());

}

w = w + Separator;

s2 = w + s2;

s1 = s1.substr(0, s1.length() - len);

}

return s2;

}

//中文分词,先分出数字

string cn_segment(string s1)

{

//先分出数字和字母

string s2;

int p1,p2;

p1 = p2 = 0;

while (p2 < s1.length()){

while ( p2 <= (s1.length()-UTF8_CN_LEN) &&

( s1.substr(p2,UTF8_CN_LEN).at(0)<'0'||s1.substr(p2,UTF8_CN_LEN).at(0)>'9' )){//不是数字或字母

p2 += UTF8_CN_LEN;

}

s2 += dict_segment(s1.substr(p1,p2-p1));//之前的句子用词典分词

//将数字和字母分出来

p1 = p2;

p2 += 3;

while ( p2 <= (s1.length()-UTF8_CN_LEN) &&

( s1.substr(p2,UTF8_CN_LEN).at(0)>='0'&&s1.substr(p2,UTF8_CN_LEN).at(0)<='9' )){//是数字或字母

p2 += UTF8_CN_LEN;

相关文档
最新文档