用DELPHI做一个东西,希望能自动将一篇中文文章中出现比较多(词频)、内容比较重要(权重)的单词自动的切分出来(中文分词)。
自己写出来一段代码,思路是这样的:
1.首先将分词字典用HashStringList载入,用Hash查找比较快。
2.将所有的标点符号都看成分隔符。(具体实现是将所有中英文的标点符号都替换成换行回车,然后对每一行进行中文分词)
3.对每一个句子进行中文分词。
具体实现是,
3.1从句子第一个字开始,每次加一个字组成字符串,用这个字符串在字典中进行HASH查找
3.2找到就从下一个位置,再取两个(及以上的)字出来查HASH字典,直到句子结束;
3.3如果到句子结束也没找到,那么开始位置加1,再回到3.2循环查找直到句子结束。
这个算法简单也比较容易实现,缺点是时间复杂度太高。一篇2000字左右的文章,大概需要3-6秒左右的时间才能完成分词。如果文章长达1W字,时间需要8-10秒甚至更长的时间。这样就有点太慢了,不能满足使用要求。
对了,电脑配置是:CPU Intel Celeron 1G,512 SDRAM,40G HDD.
在网上一阵狂搜索,找到这篇觉得思路不错,决定就这样开始了。
http://blog.donews.com/dgsheng/archive/2006/03/02/749512.aspx
浙大一位同学的中文分词算法
现在的问题是怎么用DELPHI实现。
开始的时候,我是这么定义单个字的节点的,
TWordData = record
Index:Integer;
ChildCount:Integer;
EndState:Shortint;
Word:WideChar;
ParentIndex:Integer;
ChildListIndex:array of Integer;
end;
好不容易写了一段代码,准备将现成的一个字典转换成这种格式来存储。
代码运行起来速度不慢,但是我没看到运行结束,因为出错了:Out of Memory
狂汗!
(对了刚才忘了说,我的字典也是从网上找的,里面有26万个单词。)
没办法只好把字节点的定义修改成:
TWordItem = record
Index:Integer;
ChildCount:Integer;
EndState:Shortint;
Word:WideChar;
Parent:^TWordItem;
Childs:array of ^TWordItem;
end;
这样还不错,改改程序以后大概跑了5-6分钟,26万个单词就转换过来了。
现在问题又来了,DELPHI要怎么将包含指针的数据存储成物理文件(序列化)?总不能每次载入字典的时候,都先花5-6分钟的时间转换吧?
“咔”!
欲知后事如何,请听下回分解...