一种基于自动机的快速分词方法
分词是自然语言处理入门的第一步,我参照导师的论文和写了一个基于自动机的快速分词方法;
其主要内容是字典的构建,字典的结构能够决定分词的效率;
本系统分词的实现,第一个字的查找采用的是hash,分词的时间复杂度为O(1);第二个字的查找是用二分查找实现的,时间复杂度为1+log2(n);其余部分采用的是顺序查找,整体的时间复杂度跟词的长度有关。
实现的框架如下:
const int START1 = 0XB0, START2 = 0XA1, END1 = 0XF8, END2 = 0XFF; //不用说,这个对于自然语言处理的人都知道是什么意思;
const int MAXWORDLEN = 48; //读文件的长度;
struct ThirdWord //除了第一二个字之外,其他字存储的数据节点;
{
string key; //存的是这个字;
bool isPhrase; //以这个字结尾有没有形成一个词?
ThirdWord *L,*R; //L表示的是与该节点同一层次的节点的指针,R表示的是该节点的下一个字,或者说是当前词中这个字的下一个字;
ThirdWord(string Key, bool IsPhrase = false, ThirdWord* l = 0, ThirdWord* r = 0): //构造函数咯;
key(Key), isPhrase(IsPhrase), L(l), R(r) {}
};
struct SecondWord //第二个字节点
{
string key; //存这个字
bool isPhrase; //... ...
ThirdWord *child; //指向儿子节点,也就是它后面的字节点;
SecondWord(string Key,bool IsPhrase ,ThirdWord* Child):
key(Key),isPhrase(IsPhrase),child(Child) {}
};
struct HeadWord
{
string key; //第一个字;
vector<SecondWord> secWord; //第二个字的表;
};
class Dictionary //字典类;
{
private :
ifstream fin; //读文件的;
vector <HeadWord> head; //第一个字表;
int HASH[END1-START1+1][END2-START2+1]; //哈希表,存的是当前字在head中对应的下标;
int getNumber(); //读书字;
bool IsCC(char c); //是中文字;
bool IsEC(char c); //是英文字;
string getLine(); //读一行;
void loadDictionary(); //加载字典;
int StrtoInt(string s); //转化,string到int;
unsigned CharToInt(char c); //转化;
int biSearch(unsigned x,string secWd); //二分查找;
ThirdWord* seqSearch(ThirdWord* p, string cc); //第三个字开始的查找;
void printRemain(string s,ThirdWord* &child); //打印第二个字后面的;
void processRemain(string s , ThirdWord* &child); //处理第二个字后面的;
void skipNoChinese(string s, vector<string> &test,unsigned &sp, unsigned &ep); //跳过非中文开头的字;
public :
Dictionary(string file); //构造字典;
void print(); //打印;
void segment(string s,vector<string> & test); //分词;
};
浙公网安备 33010602011771号