今天弄了一下人名转拼音的算法, 首先网上搜了一下方案,发现C#大体上有如下几个解决方案:
- 根据ASCII码定义拼音库
- 微软PinYinConverter
- Npinyin
实际使用了一下,对多音字的支持都不行,并且有的文字还覆盖不全,基本上无法满足生产需求。另外,人名转拼音还有一些特殊的规则,一些字在作为姓的时候有特殊的读法,如单、乐、查、万俟等。这些也是上述库所无法支持的。
既然没有找到合适的,就只好自己写了,要实现相对较为完善的人名转拼音,得维护一个字典词库才行,于是我便到网上搜了一下,找到了一个非常好用的字典词库 CC-CEDICT 。这个词典非常适合中文转拼音的这个需求,它具有如下特点:
- 词库免费,可以直接下载
- 词库非常小,只有8m,如果只针对对人名转拼音方案还可以进一步压缩。
- 词库比较全面,生僻字基本上都有覆盖
- 词库就是一个文本文件,并且解析非常简单
- 词库包含简繁对照,可以方便繁体字转换
- 词库包含词语的拼音,可以解决多音字问题
- 词库包含作为姓的时候的特殊发音,并且支持复姓。
有了这个词库后,就可以非常方便的实现人名转拼音方案了,具体步骤如下:
- 解析CC-CEDICT词库,将其保存到内存中,分别存为单独的姓转拼音词典和名转拼音词典,
- 将姓名中的繁体字转换为简体字
- 对姓名进行分词,分为姓和名称两部分
- 对于姓,从姓转拼音的词典中查询,无法查询则按单字查询
- 对于名字,从名字转拼音的词典中查询,如果查询不到,则拆分为单个的汉字,依次查询,多音字取第一个。
- 对于不能覆盖的规则,支持自定义词典,优先使用自定义词典
这种方案有如下优点:
- 姓转拼音是单独的字典,解决了姓的特殊发音问题
- 名字是尽量按词语匹配的,能很大程度解决多音字的问题。
- 支持繁体字
- 词库比较全,支持生僻字
相对现有的几个方案来比较,这个方案主要缺点是占内存些,试了一下,要多占30+mb内存,不过在这个手机内存都是8g起步的年代,这点内存占用就算作为桌面程序都能接受,更何况我是打算将其作为一个rest服务来使用的,更不用考虑其开销了。
不过,这个方案也不是完美的,本身姓名的读法可能也是有争议的,例如"李重",到底是发"Li Chong"还是"Li Zhong",本身就没有一个权威的说法。