ICTCLAS代码学习笔记之Utility

Utility.h和Utility.cpp是一些常调用的公有函数的集合。声明了一些宏和字符串操作的一些函数,具体说明如下:
定义了句子开始标记CT_SENTENCE_BEGIN和结束标记CT_SENTENCE_END。定义了字符(包括单字节和双字节)的类型属性:单字节字符CT_SINGLE,一般为ASCII码范畴字符;分割符CT_DELIMITER主要为双字节情况,对于单字节的分割符在当前版本中也使用CT_DELIMITER表示,但是在我的改进版中引入了CT_SINGLE_DELIMITER来区别;CT_CHINESE为汉字;CT_LETTER为双字节字母;CT_NUM数字符号,只包括双字节的情况,在我的改进版中引入了CT_SINGLE_NUM区别单字节的数字字符。CT_INDEX为索引字符,其他的双字节字符都使用CT_OTHER表示。//?需要再确认一下的是全角的空格是哪一类?
定义了一些常用的后缀,包括单字的POSTFIX_SINGLE和多字的POSTFIX_MUTIPLE;
定义了一些译名常用汉字,包括英语译名常用字TRANS_ENGLISH、俄语译名常用字TRANS_RUSSIAN及日本人名常用汉字TRANS_JAPANESE。特别注意一下的是前两个常用字中“·”这个特殊的字,而真正使用时这个字不应该在人名的第一个。相应的,定义了三种译名翻译类型TT_ENGLISH,TT_RUSSIAN和TT_JAPANESE。
定义了一些分割符,包括全角的句子分割符SEPERATOR_C_SENTENCE,全角的子句分割符SEPERATOR_C_SUB_SENTENCE,半角的句子分割符SEPERATOR_E_SENTENCE,半角的子句分割符SEPERATOR_E_SUB_SENTENCE及连接符SEPERATOR_LINK。在这些定义中有几点要说明一下:
1. 全角的句子分割符中列出了全角的冒号:但是其实还有另外两种表示方法﹕和︰。
2. 全角的子句分割符中列出了全角的双引号“”及单引号‘’,但是其实有其他几种表示方法,分别是〝〞‵′ˋˊ。
3. 连接符中除了/n和/r以外,还有全角和半角的空格,也就是说,如果输入的汉语句子中有空格,则被视为天然的分割符。//!应该补充一下制表符的判断,因为也是天然的分割符。
4. 无论是全角还是半角分割符都没有列出点(..﹒)原因是点本身的属性具有歧义性,必须要按上下文相关内容进行判断。
定义了句子起始字符串SENTENCE_BEGIN、SENTENCE_END及在计算过程中的两个词之间的词分割符WORD_SEGMENTER
下面是所有函数的说明及其注意事项:
bool GB2312_Generate(char *sFileName);
生成BG2312编码的所有字符的文件,写入sFileName中。GB2312编码高位从161到255,低位从161到255,均为左闭右开区间。
bool CC_Generate(char *sFileName);
生成汉字列表及编码到sFileName文件中,其中汉字的编码高位从176到255,低位从161到255,均为左闭右开区间。

char *CC_Find(const char *string, const char *strCharSet);

常用函数,用于双字节字符子串的匹配,要求string的内容均为双字节。如果找到则返回字符串指针否则返回NULL,常常用于判断一个汉字是否为指定的若干个汉字中的一个。
int charType(unsigned char *sChar);
判断传入的单字节或者双字节字符的类型。常用函数。该函数中的类型判断对后续的粗分及其他操作都有重要的影响,本人加入了对于CT_SINGLE_DELIMITER和CT_SINGLE_NUM的处理,前者所包含的半角字符的类型与数字串和时间词串的识别有重要的影响,要十分慎重。例如-的判断目前不敢加入到CT_SINGLE_DELIMITER中。
unsigned int GetCCPrefix(unsigned char *sSentence);
求最大的汉字串前缀,返回输入字符串中非汉字的第一个位置,注意汉字的编码范围为175到248,均为开区间。

bool IsAllChinese(unsigned char *sString);
这个函数前的注释部分有误,写的是IsAllSingleByte函数的相关说明,在新版本中要注意改掉。这个函数用于判断输入串是否均为汉字组成。
bool IsAllNonChinese(unsigned char *sString);
与上一个函数相反,判断是否全都不是汉字,只要有一个汉字即返回true。
bool IsAllSingleByte(unsigned char *sString);
判断是否全为单字节。
bool IsAllNum(unsigned char *sString);
这个函数判断输入的字符串是否全为数字,原有的函数被改写了。这个函数主要判断全角和半角的阿拉伯数字组成的相应字符串是否为数词,同时要处理的还有前缀“第”及表示正负的前缀符号,词串中可能出现的连接符例如冒号、点及表示分之或者除的左斜杆,另外就是词末的表示单词的百千万等后缀。//?很重要。
bool IsAllIndex(unsigned char *sString);
判断输入的字符中是否全由索引字符组成。除了类型判断为CT_INDEX的字符之外还包括大小写字母的情况。
bool IsAllLetter(unsigned char *sString);
判断输入的字符是否全由类型为CT_LETTER的字符组成。

bool IsAllDelimiter(unsigned char *sString);
判断输入的字符是否全由类型为CT_DELIMTER的字符组成,注意这里是双字节字符。
int BinarySearch(int nVal, int *nTable,int nTableLen);
二分查找函数,返回索引,找不到返回-1。
bool IsForeign(char *sWord);
判断输入的字符串是否为外来词翻译,计算输入串中含有的外来词的个数,如果字符串长度大于2或者外来字个数不少于长度的一半则认为可能为外来语。
bool IsAllForeign(char *sWord);
判断是否全为外来词,即要求字符串中含有的外来词的个数恰好等于字符串的长度,而且都是双字节的。
bool IsAllChineseNum(char *sWord);
另外一个判断是否为数词表达式的函数,主要判断的是全角的汉字数字例如零一二三等,会加入常用数词前缀,但是原始版本对于前缀与汉字数字的组合情况没有做一定的规则约束。另外就是汉字○〇是两个不同的字符没有补全。目前版本仍然不够完备。

int GetForeignCharCount(char *sWord);

主要就是根据预定义的译名常用汉字统计出字符串中可能为译语人名的汉字的个数,取最大的那个。
int GetCharCount(char *sCharSet,char *sWord);
这个函数用来判断输入的sWord中含有多少个已给定的字符列表中的字符的个数,注意sCharSet可以即有双字节字符又有单字节字符,返回的值以字计算,即双字节也计一个。
int GetForeignType(char *sWord);
根据输入的词串中译语字的个数来猜测人名的类型,取匹配字数最多的那一个,如果字数相同,则英文人名优先于俄语人名优先于日语人名。如果即要知道匹配的字符又要知道是哪个类型,在GetForeignCharCount和当前这个函数中会有重复操作。

bool PostfixSplit(char *sWord, char *sWordRet, char *sPostfix);
顾名思义是进行后缀的切割工作。后缀主要是地名所用到的内容。优先匹配多字节的部分,其次匹配单字节的情况,如果找到则将输入的字符串切割成两部分。如果没有找到,那么不切割输入的词串,后缀buffer置为空。该函数始终返回true。
对该文件的总结:
主要是常用的操作,有一些操作的代码,例如在判断是否全部为汉字的函数IsAllChinese中,仍然对其字节值进行了大于175小于248的判断,同样的判断在charType函数中也出现。直接在IsAllChinese函数中调用charType来判断返回值是否为CT_CHINESE可能会有性能上的损失,可以写一些inline函数将这些重复代码整合到一起,毕竟使用裸的数值本身就不太好,更何况在多处使用。

另外,纵观代码的其他部分,常常使用到一个操作就是从字符串中的某个指定位置读入一个字到buffer中,可能是双字节也可能是单字节,并相应修改下次读入的位置,这部分重复操作很多,应该写成一个函数供调用。事实上,2.0以后的版本中确实有该函数,形式为unsigned int Getchar(char *sBuffer, char *sChar);其中的返加值为读入的字符串的长度,可能为0、1或者2。
CdynamicArray是一个动态二维数据实现,而且是稀疏矩阵的实现策略,同时使用单链表进行存储。记录着每个结点的行列值、词的字符串表示方式、字符串长度,词性及value值。其实可以简单的使用一个list来实现。有趣的一点是,这个动态数组可以是行优先也可以是列优先的。动态数组提供以下功能:
SetRowFirst:设置行优先或者列优先:主要是在内部通过一个bool量来标记;
获取动态数组的头GetHead或者尾GetTail,如果是尾的话同时返回元素个数。
GetElement:有两种重载形式,一种获取给定位置上的元素的value值,如果需要同时返回词性和词的字符表达形式。另外一种是从指定位置开始找,其实就是加快速度一些。
SetElement:设置指定位置上的元素,如果有则修改,如果没有则分配并插入到合适的位置。

SetEmpty:清空动态数组,主要是释放保存字符串所分配的空间。
另外重载了赋值操作符和等于操作符。
动态数组类的总结:
完全可以使用list来代替,最多重载list加入一个表示行优先还是列优先的成员变量。如果使用list可能要注意的就是返回值类型为位置指针的那几个,呵呵。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值