拼音助记码要有"人工智能"

本文提供了在数据库层面实现一种对多音字助记码处理时适当“人工智能”化,类似于“长春”,“人参”等与地名或药名有关时,进行合理标注。

 

文化的多样性是好事,可是汉字的多音字有时很难说得清好坏。下面就以这句话的拼音来看看,WORD和WPS的拼音指南给我们的汉字如何进行拼音标注,其中WPS2009是这样标注的:

 

而在WORD中的拼音标注是这样的:

 

从中可以看出“长”和“参”在其中作为多音字有“多可爱”,就算是同样的长字,它们之间的处理方法也不一样(也许只是基础数据上的差异也不一定),在我们程序中给相关中文实现拼音助记码时,同样也面临多音字的问题,比如“长春新碱”,正规的拼音助记码应就是“CCXJ”。所以在布置拼音码字典时要处理以下问题:

1、单字或者是语义无关时,使用频度较高字的拼音,比如“参”字,大部分时间是“CAN”,只有人参时才叫“RENSHEN”,当然象刘罗锅那样“参人”的,还是念“CAN”,虽然它和“人”在一起;

2、当一个字是多音字时,就需要考虑字的上下文关系,比如我们上面所举例的“长春”和“人参”等,它与前后文字有很大关联,只在特定的环境下才读某个特殊音。

回来看我们前面举例的文字,就算是WORD和WPS对常用字或者是无关语义时的定位也不相同。所以不要指望真正能一劳永逸地解决这个问题。

在我们实现自动助记码时使用了以下的字典表:

 

代码
create table XT_HANZIKU
(
HANZI
VARCHAR2(10) not null,
QUANPIN
VARCHAR2(10),
SHURUMA1
VARCHAR2(10),
SHURUMA2
VARCHAR2(10),
SHURUMA3
VARCHAR2(10),
ID
NUMBER(10) not null,
DUOYINBZ
NUMBER(10) default 0 not null
);

 

 准备这些数据(如图003):

现在我们要解决多音字的问题,所以这个DUOYINBZ是关键,即在处理过程中需要考虑,一个汉字是否有前后语义的关系。由于不指望能通过它解决太复杂的语义问题,所以我们只采用往前后各溯一个汉字的方式来解决问题。所以我们还需要这样一张表,它用于存放我们有多音的词组即可:

 

create table XT_HANZIKU2

(

HANZI
VARCHAR2(10) not null,

CIZU
varchar(20) not null,

SHURUMA1
VARCHAR2(10)

);

 

 

以我们现在用到的单字,其中"长"和"参"有特殊意义,所以只要加入以下数据:

insert into xt_hanziku2 (HANZI, CIZU, SHURUMA1) values ('长', '长春', 'C');

insert into xt_hanziku2 (HANZI, CIZU, SHURUMA1) values ('参', '人参', 'S');

由于助记码实际上是使用首字符,如果多音字多音的首字符一样,我们就可以忽略。对于表xt_hanziku2的三个字段分别表示当前的汉字,在什么词组中和词组中该汉字的拼音首字母。

经过我们上述的分析和对汉字拼音的规则理解,最终就可以分析出助记码的实现方法(函数fun_shuruma1)是:

1、取字符信息,返回相应的首字符与多音标志;

2、如果是多音字,根据当前字符位置往前和往后查找相应的词组在XT_HANZIKU2中是否有符合数据,如果有,则取得此拼音首字符,作为助记码首字符;如果未找到,则使用第1步取得的首字符。

现在我们看一下在取输入码的函数fun_getshuruma1中,对于多音字处理的关键代码:

 

代码
select shuruma1, nvl(duoyinbz, 0) into str_pinyin, n_duoyinbz

from xt_hanziku where hanzi = str_text;

if n_duoyinbz = 1 then

str_pinyin2 :
= '';

--往前看是否是词组

if n_pos > 1 then

str_cizu :
= substr(str_mingcheng, n_pos - 1, 2);

-- 判断是否是中文词组的简洁方法

if length(str_cizu) * 2 = lengthb(str_cizu) then

select shuruma1

into str_pinyin2

from xt_hanziku2

where hanzi = str_text

and cizu = str_cizu;

end if;

--往后看是否是多音字的词组

if n_pos < n_length and str_pinyin2 is NULL then

str_cizu :
= substr(str_mingcheng, n_pos, 2);

if length(str_cizu) * 2 = lengthb(str_cizu) then

select shuruma1

into str_pinyin2

from xt_hanziku2

where hanzi = str_text

and cizu = str_cizu;

end if;

end if;

if length(str_pinyin2) > 0 then

str_pinyin :
= str_pinyin2;

end if;

end if;

 

从中可以看出,一旦我们确定了算法和合理的设计路线之后,实现起来就非常简单,最后我们看看这个函数的测试结果吧,如下图(图004)所示:

完整的函数在fun_getshuruma1.Fnc中获得(可在ORACLE中使用),对于表xt_hanziku和xt_hanziku2的表结构已经在文中描述。而且以后再涉及多音字的情况,一般都可以打上多音字的标志后再维护xt_hanziku2中的词组信息即可。它也算是解决多音字助记码的一个"智库"了。

posted @ 2010-03-17 11:22  妖精总比想象多  阅读(2881)  评论(5编辑  收藏  举报