写了个五笔码表管理器

缘起

最近学会了五笔输入法。我学的是新世纪版,因版权原因,网络上的码表资源不多,很多爱好者都自己制作码表,而且很少对外传播。作为程序员,在这方面有得天独厚的优势,于是用C++写了个五笔码表管理工具RimeWubiDictMngr。我没有使用C++标准库,而是用的Qt基础库,主要原因是QString对Unicode支持很好,处理汉字很方便。该工具暂时没有界面,只能称作一个功能简单的库,以后有必要再添加界面。

码表格式

我用的是Rime输入法,它的优点在于,码表包含权重(weight)信息,码表文件wubinc.dict.yaml的部分条目如下:

1
2
3
4
5
	ukj	113738
问题 ukjg 20455144
总是 ukjg 2866329
总量 ukjg 751184
ukjh 90990

每一行包含三个字段,依次是:词语(text),编码(code)和权重(weight),用制表符\t隔开。当出现重码时,例如,编码ukjg对应三个词,“问题”一词的权重最大,会排在候选框的最前面。

必备资源

对五笔输入法而言,编码表是最核心的。编码表的内容是汉字对应的五笔编码,有了单字的五笔编码,就能根据规则生成词组的编码。不同的版本(86版、98版和新世纪版)对应不同的编码表。本文以新世纪版为例,如果需要生成其它版本的码表,更换编码表即可。项目resource目录中的hanzi_code.txt文件即为编码表(由于版权原因,未提供完整文件,请自行解决)。文件内容如下:

1
2
3
4
5
6
	a
aa
aaa
aaaa
aaaa
aaab

要生成高质量的码表,少不了词频表。词频表是字词使用频率的信息,词频越高,字词越常见。本工具以词频为依据分配权重。词频表来自BLCU Chinese Corpuswebdict。我将它们合并得到了一个总表,有超过150万个词。舍弃词频小于1000的词语,最后剩下141810个。项目resource目录中的word_freq.txt文件即为词频表,它的部分内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	1017399760
269794532
.
. # 省略若干
.
我们 44509105
.
. # 省略很多
.
文过饰非 3220
.
. # 省略很多
.
不合格率 1000
不入耳 1000

使用方法

扩充基础词库

以其它软件(如QQ五笔,极点五笔)的词库(必须为文本文件)为参考,添加其中的词汇,扩充码表。如果已有的码表文件为空,那么实际上是从零开始构建基础码表。使用示例如下:

1
2
3
4
5
6
7
8
RimeWubiDictMngr rwdm;

// 加载已有码表,如果文件为空,则从零开始生成码表
rwdm.loadMainDict("dict.yaml");
// 扩充码表,ADD_HIGH表示只提取高频词(以词频表为依据),其它舍弃
rwdm.expandMainDict("qq_wubi.txt", RimeWubiDictMngr::ADD_HIGH);
// 保存码表到文件
rwdm.saveMainDict("full_result.txt");

添加自定义词组

例如专业词汇、朋友姓名等。如果文件中的词汇在词频表中,根据词频分配权重;如果不在,分配默认权重。使用方法如下:

1
2
3
4
5
6
7
8
9
10
RimeWubiDictMngr rwdm;

// 加载已有码表
rwdm.loadMainDict("dict.yaml");
// 添加用户词汇,ADD_ALL表示提取文件中所有词汇
rwdm.expandMainDict("names.txt", RimeWubiDictMngr::ADD_ALL);
// 将添加进去的用户词汇单独保存
rwdm.saveUserDict("names.dict.txt");
// 保存总码表到文件
rwdm.saveMainDict("full_result.txt");

制作码表文件

项目的resource目录下分别有后缀为headtail的文件,是Rime五笔码表文件的头部和尾部内容。为上述步骤中生成的full_result.txt文件添加头部和尾部,即为标准可用的码表文件。

码表格式转换

不同五笔输入法软件的码表格式不同,可以通过深蓝词库转换工具将Rime的码表转换成其它软件的格式。