不堪被 windows 升级弹窗骚扰,终于升到了 windows 10 。最不能忍受的是新的中文输入法,之前用的智能 ABC 已经完全不能用了。btw, 我爹他老人家就是因为没有 ABC 完全输入不了汉字,又重装了系统,退回 windows 7 去了。我没那么能折腾,所以还是想别的招。
很多年前我就写过,为什么我需要 智能 ABC ,到今天观点还是没有变。我听说 QQ 拼音加入了 ABC 模式,其实就是加了 5 个笔画,它并没有理解 ABC 为什么那样设计,所以做的并不好。
并不是说 ABC 设计的多完美,如果我来设计我期望的中文输入法,肯定有很多想法和 ABC 的设计不同。但是其核心是一样的:那就是,赋予每个汉字更多的编码形式,结合词(不是句子)尽可能的减少重码。
从读音看,汉字有 10 多个常用音节,30 多个次常用音节,60 多个不太常用音节。一共 100 多个,用来表示 3000 多个常用字已经是 20 倍以上的重码率了。所以对于一些同音字多的音节上,一次 10 个候选字都需要排好几页。光用拼音输入单字肯定是效率非常低下的,这也是为什么早期有很多形码输入法的原因。
如果以词为单位输入,即使仅靠读音,已经可以大大减少重码率。但问题在于不断有新词出现,尤其是很多谐音词,本身就是刻意和传统词同音的。如果我们为了行文需要去修改已有词里的单字,只靠单字的读音来索字就会变得输入效率及其低下。
大部分人都会在需要输入单字的时候(最常见是输入非名人的人名)刻意去组词,然后删掉不需要的辅字。当需要的字是在词前的时候,多敲一次退格键即可;而在需要的字在词后的时候,就麻烦的多:你需要用方向键前移,删除,再移回去。
ABC 发明了一种方法,就是用 [ ] 直接从词索字。方法是你可以输入一个词,直接加上 [ ,就只提交该词的首字。这是个好主意,但解决的还不够彻底,我认为并没有看到本质,后面会继续展开。
当用词输入还是解决不了重码造成的输入效率低下时,许多人想到了用整句输入。因为人之间口头交流时,很少有听完完整的句子还产生误解的。只要提高断句算法的正确率,辅以海量的云词库,总可以进一步的减少同音重码率的。
我认为这是一条邪路。可能某些人觉得好,但至少不适合我。
我希望在输入汉字的时候,总是能保证立刻得到正确的字,而不是整句输入后,再检查有没有错误,并回头修改。人总是懒的,往往也就不改了。时刻关注自己过去输入的整句中有没有别字,程序有没有纠正过来,也是极大的负担。更何况,输入单字,以及词库中没有的词(尤其是人名)是无法回避的需求,靠断句来自动选字是不可能的。
我的个人观点:即使是整句输入,由人主动来分词断句就足够了,不必苛求算法。人敲键盘的效率是远远超过理想状态下输入汉字的速度需求的。如果我们在输入汉字的时候,每次完成一个词多按一次空格表示分词,这多一次的键击,并不会降低输入速度,但却可以完成算法很难做到,做好的工作。
下面来谈谈我认为的 ABC 输入法的核心理念:每个汉字都有多种编码方案,而不是一种。
汉字的读音是汉字的一种编码。由于汉语拼音的普及,可以视为额外记忆量最少的自然编码。当然也有例外,像我爹几乎没有学过汉语拼音,但他懂英文,所以靠读音能判断出每个字的声母,但韵母继续是无法正确拼写的。这也是他依赖 ABC 而无法用其他拼音输入法的原因。
由于方言口音的存在,事实上输入法在实现的时候都允许了一字多码。比如 z c s 和 zh ch sh 的混用。通常,这是专门写代码实现的,并非真的把汉字赋予多个编码。
汉字的字形是另一种编码,但如何把二维结构的汉字拆分成更简单的元素没有定法。早期的形码为了追求更短的编码,更少的重码,都强迫人去机械记忆大量的知识。除了五笔,有人还记得 windows 早期带的郑码么?但大多数人是讨厌机械记忆的,只要系统不默认提供,势必淘汰。
能留下来的形码只能是笔画了。横竖撇捺折对应 1 2 3 4 5 ,记忆负担并不比汉语拼音难记。虽然一笔笔写字效率很低,但偶尔用用尚可。
ABC 的编码方式是每个汉字可以用全拼,可以用全拼加笔画,可以声母加笔画。以词为输入的单位,即用户输入他认为的一个词元素(可以是双字词、多字词或单字)后,主动敲一下回车作为分词。构成词的单字的编码可以任意选择:可以用全拼、声母、全拼加笔画、声母加笔画。
由于其实我们日常用的词和字并不多,尝试输入几次后,你一定可以找到重码最少的组合。这种学习成本非常低,但是输入效率是极高的。
ABC 在提高笔画的效率方面还额外做了一些工作。比如它会把汉字拆分成自然部分,左右结构,上下结构,包围结构等。每个部分最多只支持 3 笔。这回避了很多同音字的偏旁相同,结果连输很多笔并不能去重。
对于常见的起笔,比如交叉和口字,单独安排了 7,8 两个数字表示(6 表示弯,用的不多)。我认为实践中非常有用,但有人觉得增加了记忆量而不喜欢。
其实这是 ABC 自身没有设计好的一点,它完全可以贯彻一字多码的核心思想。例如,吴这个常见单字,你可以编码成 wu8 (8 表示起笔是个口)同时你也可以编码成 wu25 (竖折),用户输入哪个都没关系。像 QQ 拼音模仿的 ABC 模式,只支持 12345 并一笔笔编码到底的方式,我个人认为是制作人员懒得制作码表的缘故。(汉字笔画表可以在互联网找到,而汉字拆分的信息,虽然有研究者在做,但数据很难免费得到。有兴趣的同学可以 根据这个索引资料。)
其实原版的 ABC 还包含全形码的编码,不知道为什么在开发 windows 时被去掉了。我认为完全不影响使用,爱用不用,不会增加记忆负担。
另外,以词定字的功能也仅支持输入单字,而不能扩展成对单字的编码。例如,大部分输入法在第一次输入不存在的词的时候都可以默认造词;我们如果明知道这个是新词希望造词时,都会尽量提供更多信息。如果要输入一个人名,姓陈,我们平常会组个词,比如说名人:陈毅的陈 chenyi[ ,或耳东陈 erdongc] 。那么 chenyi[ 和 erdongc] 其实都是对陈的编码。这里 [ ] 是使用 ABC 规则,使用前面的词的首字或末字。
ABC 是不支持将 [ ] 规则用在组词中的,我觉得完全应该支持,也并不麻烦。
我理想中的给自己用的汉字输入法应当是这样的:
允许对单个汉字做非常多的编码,包括全拼、声调、笔画,以及它们的组合。
以词为输入单位,每个自然词(或单字)结束后,主动按空格表示输入结束,进入选词状态。构成词的单字可以用任意编码做搭配。编码有足够的容错性。不存在词库中的词立刻造出来,保存在用户词库。由于日常输入需要的词不会太多,所以适应一段时间后就能满足用词需要。
具体编码方案:笔画使用 1-9 ,1-5 留作五个基本笔画; 6-8 保留 ABC 方案(我个人已经积累了大量 ABC 经验,不需要放弃)9 表示这是个独立字或结构过于复杂(无法拆分,或拆分不确定)可选加在编码最后一位。
每个偏旁部首,只做两个数字的编码(ABC 是做多三个);汉字最多拆分成两个部分(明显的偏旁加剩余的部分);所以笔画编码最多 4 个数字,笔画不是为了确定唯一汉字,而是辅助去重。
声调可以用 01 02 03 04 05 来表示,掺杂在编码中可选。不必强求写在笔画前面还是笔画后面,或是只输入声调不输入笔画。0 起头是为了严格和笔画数字分开。
支持全笔画选单字,只用于不常用字。以 v 开头,加上两个部分的笔画。所以通常是 v 加 4 个数字或是 v 加两个数字加 9 表示。同时支持偏旁不用数字而使用偏旁的读音。比如 dr 单人旁,sr 双人旁,ts 提手旁等等。同时可以把部首的第二部分输入全拼。这对于拿不准读音,读半边字的情况,或是不知道怎么组词,但却想输入的单字特别有用。
比如:
墉 可以编码成 vtuyong (提土旁加一个 yong 字)
镛 v31yong (偏旁起笔为撇3横1, 右边是个 yong 字)
这些也是作为额外辅助编码,爱用就用,不用不用管的特性。整个单字输入的重点就在于,提供可以想到的检索方案放在那里,想用的时候就用的到,不用的时候也不干扰输入。和五笔这些传统形码不同,不追求怎么编码短,重码低;毕竟日常输入不常见单字的需求并不多,力求做到不用记忆,宁可编码长一些也尽量准确。
我在自己用的输入法上面已经花了几天时间做了一些开发工作。强调是自己用是因为可以无视别人的需求,不用和人解释为什么会设计成这个样子。每个人的情况不同,照顾大多数的习惯就会强迫自己改变习惯;同样自己已经熟悉的东西,比如 ABC 的笔画方案继承下来完全没有记忆负担,换个人会因为不想记忆而排斥。
我会以开源的方式开发,但不会宣传,这里也不会给出 github 地址。没有给自己定计划,想到了就做一点吧。明天可能会继续写一些 windows 下坑爹的输入法开发踩的坑。
ps,前几天在微博曾经吐槽现在的输入法对程序员及其不友好。中英文混合输入,以及偶尔写几个汉字,大部分时间敲英文的场合也照顾的不好。怎样让中文输入法尽量配合我这种大部分时间在敲代码,或是控制台命令的人,尽量少去主动切换中英文状态,关于这方面的想法过几天再专文写写。