Skip to main content Link Menu Expand (external link) Document Search Copy Copied

宇浩输入法详细教程和规则细节

目录
  1. 宇浩输入法详细教程和规则细节
    1. 初识宇浩
      1. 汉字输入法
        1. 输入法种类
        2. 形码和音码的对比
      2. 宇浩输入法特点
      3. 学习步骤
    2. 字根编码
      1. 常用字根
      2. 大码和小码
      3. 字根图
      4. 光华方案字根编码规律
        1. 字根大码
        2. 字根小码
      5. 星陳方案字根编码规律
        1. 字根大码
        2. 字根小码
    3. 拆字规则
      1. 字根最少
      2. 符合笔顺
      3. 结构完整
      4. 散连交断
      5. 字根取大
      6. 机器实现
      7. 拆字举例
    4. 汉字编码规则
      1. 多字根字编码
      2. 单字根字编码
      3. 空格键的使用
    5. 简码设置
      1. 一级简码字
      2. 二级简码字
      3. 三级简码字
    6. 词语编码规则
      1. 两字词
      2. 三字词
      3. 四字词及以上
      4. 词语输入的优缺点
    7. 进阶讨论
      1. 字形选取的标准
      2. 字根的内在属性
        1. 日曰之辨
        2. 勹𠂊之辨
        3. 人八入之辨
        4. 口中无整画
      3. 汉字的拆分禁手
        1. 散件不分割
        2. 竖向不包夹
        3. 横间不穿心
    8. 脚注

初识宇浩

汉字输入法

汉字输入法,顾名思义,就是汉字(部首、笔画)录入进电脑中的方法。大多数时候,输入的过程,有两个阶段:

  1. 用户将汉字,用一定规则,编成一串字母、数字、符号的组合,输入电脑中。
  2. 输入法会串字符,根据一定的规则,转化为对应的汉字,显示到屏幕上。

本教程中的「输入法」,特别指代上文中提到的第一阶段,亦即:用户将汉字,用一定规则,编成一串字母、数字、符号的组合,输入电脑中,并获得想要的汉字。

输入法种类

输入法,根据其特点,一般分为三类

  • 拼音(音码)
  • 字形(形码)
  • 音形(形音)混合。

音码输入法,最常见的例子就是拼音。我们将汉字对应的拼音,直接输入到软件中,软件会显示对应的汉字供你选择。这其中包括了一个反馈的过程,即:输入字母——获得候选——输入数字——获得汉字。

形码输入法,最常见的例子是五笔字型。我们将汉字拆成若干部件,输入每一个部件对应的代码,软件会显示出汉字。常见的形码,还包括五笔字型,郑码,仓颉等等。这其中有时包括了一个反馈的过程,但因为形码的确定性,大多数时候是不需要确认的,即:输入字母——获得汉字。

判断一个输入法是音码还是形码的最简单的方法,就是:对于任意一个汉字,不用知道它本身的读音便能输入。

因此,「宇浩」繁简通打输入法,是一种形码输入法。

形码和音码的对比

形码输入法和拼音最大的区别,在于拼音输入法,知道读音,便能输入汉字。而形码输入法,知道写法,便能输入汉字。

音码的优点,便是像说话一样去打字。你只要知道标准的发音,便可以打出字来。同时,汉语拼音也是当代人的必修课,不需要特别地学习,因此,它的学习成本近乎为零。

音码的缺点,那便是同音字很多,经常需要选字。虽然当代的不少输入软片在「智能化」上下足了工夫,但在输入一些书面语、古文、或者生僻字词时,还是需要选字。大量翻页会打输入的节奏。笔者正是因为写小说时候被翻页打断思路而使用了形码。

形码的优点,便是像写字一样去打字。你不需要知道每个字的具体读音。同时,因为编码比较离散,你甚至不怎么需要去选字。这在写作时,保证你的思路不被打断。在看打、或者打古文的时候,形码的速度很快。

形码缺点是,如果你一下字忘了这个字的写法,那就会卡住,必须临时改用拼音输入法(反查)。

至于音码和形码哪个更好?这就是仁者见仁、智者见智的问题了。当然,也依赖于你的需求和使用场合。笔者在日常对话时使用全拼,在写作时使用形码,做到扬长避短。

宇浩输入法特点

「宇浩」作为一种形码输入法,除了继承了刚刚所说的形码的全部重点外,还有一些自身的特点。这些特点,自然受到了笔者偏好的影响。这里仅举例一二:

  • 大字集。也就是说,用「宇浩」可以打出所有的汉字(CJK + 部首 + 笔画),并且有99000多个汉字的单字拆分,且一直保持保持更新维护。
  • 繁简通。也就是说,你可以直接打出繁体汉字和简化汉字。繁简字根不占用同一个码位,因此繁简混输的时候也很少选字。
  • 低重码。也就是说,每个编码一般只对应唯一的候选项,你不需要进行选字,可以不用打断思路地进行输入。
  • 手感好。笔者不喜欢使用 Z 键,所以这个键位被空了出来,用于反查或其他功能。

这里对比一下五笔、郑码、宇浩等十余种常见输入法在不同汉字字符集下重码数据,供大家参考。

学习步骤

学习「宇浩」,一般从了解拆字和熟悉字根开始。

拆字,就是把汉字按照一定的规则,拆成唯一的部件组合。拆分出来的部件,便叫做「字根」。字根不仅包括你我熟知的「偏旁部首」,也包括了一些基本笔划,甚至是一些汉字。因此,笔画输入法(横竖撇捺折),也是一种特殊的形码。那么我们为什么要创造别的形码呢?因为一个字若用十几个、甚至几十个字母代替,太没有效率。故而,我们会截取一些比较大的部件作为字根。

对于汉语使用者,拆字并不是一件陌生的事情。我们自小就学会将一个字拆成分离的部首,进行检索。大多数时候,这是非常直观的。

「部」字,大家会自然地将他拆分为「立口阝」三个部分。
「程」字,大家会自然地将他拆分为「禾口王」三个部分。

对于「宇浩」而言,大多数的字,也是这么拆分的。并且大多数的偏旁部首,也都是「字根」。所以恭喜你,对于大多数的汉字,你已经可以凭借直觉进行拆分了。

本教程推荐的学习步骤如下。

  1. 看字根图,大致了解「宇浩」的字根有哪些,以及它们对应的编码。
  2. 了解「宇浩」拆字的规则,学会如何得到唯一的拆分方法。
  3. 学习编码规则,学会如何将拆好的字根转化成最终的「宇浩」。
  4. 记诵最常用的100个字根的编码(在输入法「新手」模式下,可以基本输入最常用的500个汉字)。
  5. 直接在输入软件中练习前500常用字(覆盖了77%的字频),边练习边记忆字根。
  6. 阅读进阶教程,更加深入地了解一些「宇浩」的特点。

以上内容不论顺序,可以交叉或同步进行。

字根编码

常用字根

本章介绍宇浩输入法的字根。介绍之前,先说明一件事。

我注意到,最常用的50个字根,占了60%的使用频率。最常用的100个字根,占了85%的使用频率!这说明,有针对性的记忆字根,使得学习曲线更加平坦,收效更加显著。

按照使用频率降序,前50的常用字根为:

口一月丶日人亻扌白土丷二又丿宀木尚辶小冖厶心氵八女大艹𠂇匕寸也乙戈目讠不龰阝竹了十夂王刂儿力凵冂子斤

前51到100的常用字根为:

火米丁彐纟文立士夕乂门卜自尤彳羊止禾贝尸工乚上囗至手𬺰艮车石田己几牛见走甲且彡犬巾西方刀殳七弓巴矢示

所以,在接下来的学习中,请务必按照上面的次序记忆字根,而不是一股脑地背诵全部。先练熟边际收益高的字根,会显著加快上手打字的进程,增加学习乐趣和成就感。而偏僻的字根,可以等未来慢慢熟悉。

大码和小码

在「宇浩」中,每一个字根,都对应了两个字母。换句话说,「宇浩」使用的是双编码字根。这一点和郑码相同,和五笔不同。特别的:

  • 第一个字母叫做大码。为了方便教学,本教程用大写字母表示。大多数时候,我们只需要用到大码,所以应该重点记忆。
  • 第二个字母叫做小码。为了方便教学,本教程用小写字母表示。只有在部份情况下,需要用到,记忆起来也比较简单。

字根的大码和小码的分布,并不是随机的,而是有一定的规律。在接下来的教程中会进行介绍。

字根图

我们将字根的键位画出来,这便是字根图。每一个键位上的大写字母,就是大码,是一群字根的「家」。而字根右下角的小写字母,则是小码,也就是单个字根的「姓名」。将大码和小码组合起来,就是一个字根的编码了。

「言」这个字根,在字母U的方框里,同时,右下角的字母是a,因此,它的编码就是Ua
「其」这个字根,在字母D的方框里,同时,右下角的字母是j,因此,它的编码就是Dj

字根图是查询字根的重要工具,初学者应当时常将它放在手边,以利用查询。

繁体特有的字根只有22个,主要是位于左侧的偏旁部首。不打繁体的话,可以不用记忆。

光华方案字根编码规律

宇浩输入法宋体字根图

字根大码

光华方案中,字根大码是按照字根第一笔的笔画来制定的。同五笔一样,字根按照笔画分区。

  • ASDFGH 包含了首笔为「横」的字根,例如:A寸 F一等。横区在键盘中排左侧。
  • JKLNM 包含了首笔为「竖」的字根,例如:J日 K上等。竖区在键盘中下排右侧。
  • QWERTY 包含了首笔为「撇」的字根,例如:P竹 T人等。撇区在键盘上排左侧。
  • UIOP 包含了首笔为「捺」和「点」的字根,例如:U言 I立等。捺区在键盘上排右侧。
  • BVCX 包含了首笔为「折」的字根,例如:B刀 C巴等。折区在键盘下排左侧。
  • Z 键没有字根,可以用来反查拼音或做其他用途。

字根口诀如下:

横:
A 丁丌(jī)行右(亍)瓦,耳下(丅)打(扌丁)七寸。
S 草头二犬厂,辰考而有臣。(丂𠂇)
D 古來十石尤其戊,西雨不走馬豕丰,
F 一木甫三工。
G 大王革春(𡗗)夫,框(匚)面弋酉戈。
H 老上(耂)青(龶)士示(礻)兀牙,末世土干未至车。

竖:
J 早日山曰田,
K 甲申由禺电,下框(冂)凹里业,虫贝水上见。
L 口是心非
M 巾网(罒wǎng)貝皿且具上,小目立刀(刂)卜虎(虍)骨。
N 方框(囗)二三(丨〢〣)竖,黑册尚止(龰)足。

撇:
Q 荒下没右(殳)鱼儿气,撇(丿)川瓜矢几竹舟。
W 周围(⺆勹)炙顶(⺼)皆同月,千鬼上身生金牛(牜),告头(⺧)杀上(乂)谁侧(隹)缶?
E 反文(攵pū)人(亻)欠斤,白爪壬乌夭。
R 双人(彳)食(饣)匕入舌臼,微禾向夕反犬(犭)毛,衣下(𧘇)古風僉繁鳥。
T 八人手长二三撇(彡),金边(钅)自用介下卯。
Y 秃盖(冖mì)心合豸(zhì),阜(𠂤duī)上食九鸟。

捺点:
U 兰头(丷䒑)将(丬)左四点(灬)火,广言亡羊赢外框,
I 鹿户三点(ッ)立水(氵)上。
O 辛亥高宝盖(宀),言旁(讠)点(丶)捺(乀)方。
P 文门亦米走之底(辶chuò),病头(疒)麻穴衣字旁(衤)。

字根小码

字根的小码,都是尽量从它汉语拼音包含的字母中选取。有以下规律:

  1. 优先使用声母。
    • 如果拼音中有ZX,那么可以选K来代替。如:竹 Qk,子 Vk。
    • 如果拼音中有U,那么可以选V来代替。如:足 Nv,木 Fv。
  2. 声母被其他字根占用,或声母键位不佳,则使用韵母。如:羊 Ug,手 Tu。
  3. 为了提升手感和双手互击,偶尔也使用 d f j k i e。如:八 Ti,辶 Pd,力 Xk。

,第一笔为「点」,故而它的大码在点区的P。小码为了便于记忆,选取声母m
,第一笔为「折」,故而它的大码在折区的C。小码为了便于记忆,选取声母n

我在这里使用大写和小写的拉丁字母,是为了区分大码和小码的概念,便于理解学习。在实际打字的过程中,不需要区分大小写。

星陳方案字根编码规律

yustar

字根大码

星陳方案中,拥有相似字形的字根会抱团出现,如郑码、徐码等,但聚类强度稍弱(真码>郑码>徐码>星陈)。

每一个大码上一般有一到五组形近字根,及若干零散字根。因此,在记忆字根的时候,只需要记忆一个代表的字根,就可以联想类推出其他字根。最后,只要特别记忆一些零散字根的位置就好。

以下表格中,更加直观展示了每个按键上字根的聚类:

大码 聚类字根 零散字根
A 木來 㔾卩 亠高
B 皮又马彐尸弓丑韋(横折) 言 入
C 冂贝见冊雨(下框) 彳彡(几撇)
D 由电黽申車丰 白𠂤臼戶鬼向烏鳥斤爿片 鬥門 至 讠
E 亻𠂇隹 几殳風 乚彑母  
F 未末 手扌龵 尤尢
G 丿不竹气𧘇艮 乃廴 十 黑
H 土士壴走 匚臣牙 犬 丂 户
I 宀穴 小尚 二亍 火灬  
J 日曰早古 上丄下丅丁示 目且見貝 缶矢
K 丶乀八食 寸𬺰 了子予 立辛 弋戈戊 卯 纟
L 兀丌耳 口舌 巛川三  
M 广疒麻鹿 千壬禾夭毛豸 乌鸟 刀刂 辰{畏下}  
N 水氵 厶幺 长匕 干甫  
O 己已巳巴 大夫𡗗龶 也乜 辶之 糸 钅
P 止龰足齒 酉西 生牛
Q 丷丬羊米 自身
R 心忄 人合僉 咼骨 九瓦  
S 艹卅世革 而面 用 力 乂
T 方文夂亦亡亥豕 金 门
U 爪瓜 罒皿 長镸髟 丨卜虎鹵 〢非其业 山巾
V 田甲里禺魚(田不出头或下出头) 石厂丆 豸 习
W 月勹 囗凵丩屮(上框) 馬 儿
X 冖𠂊夕饣欠鱼 车七
Y 乙飛

字根小码

星陈方案使用强音托,字根小码 85% 以上情况下都是汉语拼音的第一个字母(yi 取 y,yu 取 v)。故而大部分的字根小码不用特别记忆,可以猜出来。

由于很多字根拼音只有两个字母,首字母容易被占用,故而 15% 情况下会选取其后续字母(主元音)作为音托。只要特别记住以下字根即可:

小码 字根 解释
a 三八麻  
o 又尤由舟 艹  
e 人文了业冊  
i ㄧ 七 心 臼  
i 矢世十 止自  
u 不夂(pū)鬥  
r ㄦ 二儿而  
v 上小口 让出声母给低频根

拆字规则

先前说过,拆字,就是把汉字按照一定的规则,拆成唯一的字根组合。这个过程如同拼图一般,大多数时候,是非常直观而自然的。

部 = 立口阝
先 = ⺧儿
国 = 囗王丶
琴 = 王王人丶乛

这种将字拆成直观的、分离的部件的方法,足以应付大部分汉字的拆分了。但在实际使用中,遇到这个问题:一个独体字,本身不是字根,怎么办?这时候,我们要把它继续拆成更小的字根甚至笔划。

「戋」这个字,我们可以继续将它拆成「一」和「戈」。查字根图可知,「一」和「戈」正好是两个字根,拆字成功。
「丸」这个字,我们可以继续将它拆成「九」和「丶」。查字根图可知,「九」和「丶」正好是两个字根,拆字成功。
「朱」这个字,我们可以继续将它拆成「牛」和「八」。查字根图可知,「牛」和「八」正好是两个字根,拆字成功。

有时候,独体字的拆分不是很直观。比如「再」拆成「王冂」两个字根。遇到此类字时的拆分,往往需要一些经验和练习。所以当你遇到不会拆的字时,应该主动查询它的编码,及时学习。

更麻烦的情况是,一个字好像有几种拆分方法

「井」,可以拆「二{介下}」,也可以拆「一廾」。
「单」可以拆成「丷日十」也可以拆成「丷冂丰」。
「兰」可以拆成「䒑二」也可以拆成「丷三」。

这种一字多拆的情况,任何形码中,都是希望避免的。因为一字多拆,会造成极大的不确定性,并造成编码的混乱。

前辈输入法的拆字规则,一般都有诸如「直观」、「符合笔顺」、「取大」等设置。但是优先级往往不够明确,很多拆分方法并不符合规则,存在不少特例。在常用字范围内,还可以通过大量练习来完成记忆,但到了大字集,规则不明确、规则相矛盾,都是造成检字困难的因素。

宇浩输入法总结了拆字规则,并且不断自我审视每一个拆分是否符合规则。通过大量的努力,明确了一套优先级系统。使每一个汉字,都有唯一的拆分方案,消除了不确定性1

「宇浩」拆字规则,按优先级排序如下:

  1. 字根最少
  2. 符合笔顺
  3. 结构完整
  4. 散连交断
  5. 字根取大

以上优先级,还可以高度归纳为:少顺整散连交断大

取根时,如果有多种不同的拆分方式,则按优先级从高到低依次检查以上规则,选取符合条件的,排除不满足的,最终得到唯一的拆分方案。因此,某种意义上来说,宇浩输入法的拆分规则,其实是一种「比较和淘汰」的排除法,后文中会展示这些步骤的机器实现

在进行拆分前,首先需要「确认」某个字根到底存不存在,是否合规,也就是检查字根的「内在属性」。比如「土」「士」,两横的长度直接决定了字根的异同。
其次需要检查一些「拆分禁手」,比如「王」中间如果被笔画「穿心」,这是不被允许的。禁手有:散件不分割、竖向不包夹、横间不穿心。
对这两点的讨论作为进阶内容,于此处跳过。若有兴趣,可以在后续章节《进阶讨论》中阅读。

以下为拆分规则详细介绍:

字根最少

字根最少,意思是拆分一个字时,应该使得字根的数量最少。保证字根数量最少,是第一优先级最高的规则。

符合笔顺

符合笔顺,指的是字根的每一笔,完全符合原汉字的笔顺。我们要使得完全合笔顺的字根尽量多。

符合笔顺的优先级低于字根最少。比如:

  • 「国」如果完全符合笔顺,应该拆成「冂王丶一」,是四个字根。但拆成「囗王丶」,只用三个字根就够了。因为「少」优先级高于「顺」,所以应该拆成「囗王丶」。

结构完整

结构完整,指的是「囗日目勹冂匚コ凵」等存在全包围和半包围结构的字根不拆散。

这个原则的设置,是为了不过分破坏汉字的整体性和直观性。

「昜」拆「日一勹彡」不拆「日丆𠃌彡」。
「万」拆成「一勹」而非「{一丿}乛」。
「单」可以拆成「丷日十」也可以拆成「丷冂丰」。两者都是三根,都完全「符合笔顺」。因为包围结构不拆散,故而「单」拆成「丷日十」。
「免」可以拆成「⺈口儿」也可以拆成「⺈冂尢」。两者都是三根,都完全「符合笔顺」。因为包围结构不拆散,故而「免」拆成「⺈口儿」。

注意,拆分的优先级需要得到贯彻:

  • 「匹」拆「兀乚」而不拆「匚儿」。因为前者完全符合笔顺,而「符合笔顺」的优先级更高。

散连交断

「散连交断」,是汉字部首或笔画的四种状态。

  • 字根离散,指的是两个字根互相分离。比如「部」中的「立口阝」,便是三个分离的字根。
  • 字根相连,指的是两个字根互相连接。比如「美」拆为「𦍌大」,这两个字根是相连的。
  • 字根相交,指的是两个字根互相交叉。比如「再」拆成「王冂」两个字根,便是相交的。
  • 笔划断开,指的是一个笔划断开。比如「我」拆成「丿扌戈」三个字根,其中的「扌」和「戈」两根的横本是一笔写成,但我们将横画断开。

「散连交断」,优先级依次下降,但都排在「字根最少」「符合笔顺」「结构完整」之後。

「兰」可以拆成「䒑二」也可以拆成「丷三」。观察到,「䒑」的两点是同一横黏在一起的。拆成「丷三」,則兩個字根相連,拆成「䒑二」則兩個字根分散。後者符合「能散不连」。
「开」可以拆成「一廾」也可以拆成「二{介下}」。观察到,第一种拆法字根相连,第二种拆法字根相交。故而拆成「一廾」符合「能连不交」。
「果」拆作「日木」,不拆成「田木」,这是因为后者将中间的竖断开了。因为「字根相交」的优先级高于「笔画断开」,「果」应当拆成「日木」。
「我」拆作「丿扌戈」,不拆成「丿扌乚丿丶」。虽然前者将中间的横断开了,但因为「字根最少」的优先级大于「笔画断开」,我们选择只有三根的「丿扌戈」。
「熏」拆作「千黑」,不拆成「千囗丷二灬」。虽然前者将中间的竖断开了,但因为「字根最少」的优先级大于「笔画断开」,我们选择只有两根的「千黑」。

字根取大

字根取大,指的是按照笔顺拆字时:

  • 让完全符合笔顺的字根尽可能地大。也就是就算做不到完全合笔顺,也要做到局部合笔顺。只要其中某个字根多写一笔仍然符合笔顺,就多写一笔。
  • 让非歪斜根尽可能地大。
  • 让首笔靠前的字根尽可能地大。

第一条的存在,是为了防止笔画过于交织而导致拆分方案不直观。

这里以「妻」字举例,「妻」可以拆分为「十彐女」「キコ女」甚至「龶乛女」。我们按顺序检查规则,发现:

  • 三者都是三根,都不完全符合笔顺,都存在相交。
  • 我们最后检查「字根取大」规则。我们发现,前两个字根是穿插书写的。「キコ女」的拆法中,前两根分成四部分写成。「十彐女」「龶乛女」,前两根只分成三部分写成,故而「キコ女」淘汰。
  • 「十彐女」中,完全合笔顺的字根「彐」写了三笔。而「龶乛女」中,完全合笔顺的字根「乛」只有一笔。
  • 「十彐女」胜出。

第二条只有一种场合会出现,那就是部分字根在做偏旁的时候,由于书法的考虑,会有「竖变撇」的变化。如:「千」字根的「丨」变成「丿」,「干」字根的「丨」变成「丿」,称为「歪斜根」。我们应当对非歪斜根取大。

「失」拆「丿夫」而不拆「牛乀」,因为「牛」的一竖是撇。故而对「夫」取大。 「井」拆「二{介下}」而不拆「キ丨」,因为因为「キ」的一竖是撇。故而对{介下}取大。 「缓」拆「纟爪干又」而不拆「纟爪二夂」。虽然前者「干」的竖是撇,但后者出现了「字根相交」。根据规则优先级,「字根相交」低于「字根相连」,故而拆为「纟爪干又」。

第三条最为常见,「让首笔靠前的字根尽可能地大」是一个兜底原则,可以保证最终只有一个候选方案能够胜出。因此,它的优先级必然是所有拆字规则中最低的。

「井」拆成「二{齐下}」,而不拆成「一廾」,因为「字根取大」原则。让首笔靠前的字根的笔划数尽量地多,这里,「二」的笔画数大于「一」。
「美」拆为「䒑土大」,而不拆成「丷王大」,因为「字根取大」原则。让首笔靠前的字根的笔划数尽量地多,这里,「䒑」的笔画数大于「丷」。

机器实现

这里释出宇浩拆分规则的伪代码,用以展示使用计算机程序来实现拆分筛选的算法逻辑。注意,宇浩的拆分规则是淘汰性而非引导性的,故而算法的前置条件是已经拥有了若干的候选拆分,在此基础上,程序可以筛选出最满足宇浩拆分规则的唯一拆分。

假设某个汉字存在N个候选拆分,记为divs = {div_i | i in [1, 2, ..., N]}。每个拆分都是字根的有序集合,记为div = {root_i | i in [1, 2, ..., M]},有以下属性:

  • div.len: int 字根个数
  • div.bishun: Booleann 字根是否完全合笔顺
  • div.san: Boolean 字根是否分散
  • div.lian: Boolean 字根是否相连
  • div.jiao: Boolean 字根是否相交
  • div.duan: Boolean 字根是否断开

注意:div.san, div.lian, div.jiao, div,duan 中有且只有一个是 True。

以下伪代码会从N个候选拆分divs = {div_i | i in [1, 2, ..., N]}中选出最优拆分:

# 字根最少
for div_i in divs:
    # 移除字根数量不是最少的候选拆分
    if div_i.len != min([i.len for i in divs]):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 符合笔顺
for div_i in divs:
    # 存在完全符合笔顺的拆分时,移除不完全符合笔顺的候选拆分
    if div_i.bishun != max([i.bishun for i in divs]):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 结构完整
root_completeness_score = {
    : 2,
    : 2,
    : 2,
    : 2,
    : 1,
    : 1,
    : 1,
    : 1,
    : 1,
    其他: 0,
}  # 包围结构得分更高
for div_i, div_j in permutation(divs, 2):  # 俩俩取候选拆分比较
    common = intersect(div_i, div_j)  # 共同的拆分部分
    unique_i = div_i.difference(common)  # 非共同的拆分部分
    unique_j = div_j.difference(common)  # 非共同的拆分部分
    # 非共同字根中有包围结构的保留
    if unique_i.map(root_completeness_score) < unique_j.map(root_completeness_score):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 字根分散
for div_i in divs:
    # 存在散的拆分时,移除不散的候选拆分
    if div_i.san != max([i.san for i in divs]):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 字根相连
for div_i in divs:
    # 存在连的拆分时,移除不连的候选拆分
    if div_i.lian != max([i.lian for i in divs]):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 字根相交
for div_i in divs:
    # 存在交的拆分时,移除不交的候选拆分
    if div_i.jiao != max([i.jiao for i in divs]):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 字根断开
# 断属性为散连交的补集,故不用再进行判断

# 字根取大之一
# 让完全符合笔顺的部件尽可能地大
for div_i, div_j in permutation(divs, 2):  # 俩俩取候选拆分比较
    common = intersect(div_i, div_j)  # 共同的拆分部分
    unique_i = div_i.difference(common)  # 非共同的拆分部分
    unique_j = div_j.difference(common)  # 非共同的拆分部分
    # root_bishun_score(div) 是局部拆分中完全符合笔顺的字根数量
    # 非共同字根中,完全符合笔顺的字根数量多的保留
    if root_bishun_score(unique_i) < root_bishun_score(unique_j):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 字根取大之二
# 让非歪斜根尽可能地大
for div_i, div_j in permutation(divs, 2):  # 俩俩取候选拆分比较
    common = intersect(div_i, div_j)  # 共同的拆分部分
    unique_i = div_i.difference(common)  # 非共同的拆分部分
    unique_j = div_j.difference(common)  # 非共同的拆分部分
    # leaning_root_strokes(div) 是局部拆分中歪斜根的笔画数
    # 非共同字根中,非歪斜根笔画多的保留
    if leaning_root_strokes(unique_i) > leaning_root_strokes(unique_j):
        divs.remove(div_i)
    if len(divs) == 1:
        break  # 剩下唯一拆分候选,则停止判断

# 字根取大之三
# 让首笔靠前的字根尽可能地大
for div_i, div_j in permutation(divs, 2):  # 俩俩取候选拆分比较
    common = intersect(div_i, div_j)  # 共同的拆分部分
    unique_i = div_i.difference(common)  # 非共同的拆分部分
    unique_j = div_j.difference(common)  # 非共同的拆分部分
    # root_i.strokes.len 是字根的笔画数
    # 非共同字根中,靠前的字根笔画多的保留
    for root_i, root_j in zip(unique_i, unique_j):  # 俩俩取字根比较
        if root_i.strokes.len < root_j.strokes.len:
            divs.remove(div_i)

# 到此,必然只剩下唯一的拆分候选,即为最终拆分

拆字举例

实际拆字时,如果你感觉拆分方法不唯一,那么可以用以下方法找到最优解:

  • 列出所有可能的候选拆分方案。
  • 依照「少顺整散连交断大」的规则顺序,依次比较各个候选拆分。
  • 如果所有的候选拆分都不满足本条规则,则进入下条规则。
  • 如果部分的候选拆分满足本条规则,则该部分的候选拆分方案进入下条规则。
  • 直到只有一个候选拆分方案胜出。

以下通过部分例字来说明拆分规则:

一例:亷。候选拆分「亠丷厂彐〢八」和「立丿彐〢八」。

  • 「亠丷厂彐〢八」六根,「立丿彐〢八」五根。后者字根最少,直接胜出。

又一例:重。候选拆分「丿車一」和「千里」。

  • 「千里」是两根,满足「字根最少」,直接虽然中间一竖断开,但依然胜出。

又一例:盡。候选拆分「コ土灬皿」「乛龶灬皿」「彐丄灬皿」「{聿上}一灬皿」四种。

  • 都是四根,同时满足「字根最少」。
  • 「コ土灬皿」不符合笔顺,其他三者都完全符合笔顺。淘汰「コ土灬皿」。
  • 上半部分都出现字根相交情况。
  • 都不适用「结构合理」。
  • 进入兜底规则「字根取大」。根据规则,只要其中某个字根多写一笔仍然符合笔顺,就多写一笔。观察到,「{聿上}一灬皿」的第一根一共写了四笔,故而胜出。

又一例:曱yuē甴yóu。

  • 「曱」按笔顺取大,故而是「日丨」。
  • 「甴」,候选拆分为「日丨」「囗丄」。两者都是两根,都未破坏包围结构,都出现了「交」。最后查看取大原则。因为先写竖,再写中间的一横,为了让完全符合笔顺的部件尽可能地大,我们取「丄」。最后「囗丄」胜出。

上面的例子逻辑虽比较复杂,但是最终的结果还是非常直观的。在宇浩输入法中,大多数的时候,直观的拆分方法往往也是符合规则的。

汉字编码规则

多字根字编码

学习了「宇浩」的拆字规则后,我们可以将任何一个汉字拆成唯一的字根组合。最后一步,便是把字根转为「宇浩」编码。

宇浩的单字编码一般是由4个字母构成。部分字根字为3个字母。

在「宇浩」中,无论一个字能拆成几个字根,我们只关心其中的四个根,分别是:

  • 第一根:首根
  • 第二根:二根
  • 第三根:三根
  • 倒数第一根:末根

这同五笔字型相同,和郑码、徐码不同。

单字编码规则如下:

  1. 依次取一、二、三、末根大码。
  2. 不足四码时,补上末根小码。
  3. 仍然不足四码时,补上首根小码。

最后一条,只有双根字中会出现。第二条,只有三根字中会出现。

「嫩」字拆成〔女木口夂〕,分别对应了首根、二根、三根、末根,我们直接取〔女Cn 木Fv 口Lv 夂Eh〕四个字根的大码 CFLE 即可出字。 「整」字拆成〔木口夂一止〕,我们只取首根、二根、三根、末根,也就是〔木Fv 口Lv 攵Eh 止Ni〕的大码,输入 FLEN 即可出字。 「算」字拆成〔竹目卄〕,只有三根,所以我们取全部根,也就是〔𥫗Qk 目Mf 廾Sj〕的大码,即 QMS。此时,注意到不足四码,故而补上最末根的小码 o。输入 QMSj 即可出字。 「织」字拆成〔纟口八〕,只有三根,所以我们取全部根大码,也就是 VLT。此时,注意到不足四码,故而补上最末根的小码 b。输入 VLTi 即可出字。 「认」字拆成〔讠人〕,只有两根,所以我们取全部根,也就是〔讠Oa 人Te〕的大码,即 OT 。此时,注意到不足四码,故而补上最末根的小码 e。注意到仍然不足四码,于是再添上首根的小码 a。输入 OTea 即可出字。 「好」字拆成〔女子〕,只有两根,所以我们取全部根,也就是〔女Cn 子Vk〕的大码,即 CV。此时,注意到不足四码,故而补上最末根的小码 k。注意到仍然不足四码,于是再添上首根的小码 n。输入 CVkn 即可出字。

末尾添加首根的小码,只是为了补齐四码的作用,只有在双根字中才会出现。

单字根字编码

很多的字根因为字形近似,被归为一个字根,由其中一个常用字为统摄,称为「代表根」,其它的字根为「被代表根」。

  • 代表字根,全码为三码:大码+小码+小码
  • 附属字根,全码为四码:大码+小码+小码+小码

代表字根:

  • 「木」是代表字根,编码为 Fvv
  • 「骨」是代表字根,编码为 Mgg

附属字根:

  • 「長」、「镸」、「髟」被归为一个字根,由「長」统摄,所以「长」的编码为 Haa,「镸」的编码为 Haaa,「髟」的编码为 Haaa
  • 「户」、「戶」、「戸」被归为一个字根,由「户」统摄,所以「户」的编码为 Iee,「戶」的编码为 Ieee,「戸」的编码为 Ieee
  • 「月」、「勹」、「⺼」被归为一个字根,由「月」统摄,所以「月」的编码为 Wyy,「勹」的编码为 Wyyy,「⺼」的编码为 Wyyy

注意到,字根字编码规则同单字编码规则是一致的:
假设字根大码为 A,小码为 a。
首先,依次取一、二、三、末根大碼,故取 A。
接着,不足四碼,故補上末根小碼,故取 a。
最後,仍然不足四碼,故補上首根小碼 a。最終編碼爲 Aaa。

Q:字根字重复小码的原因是什么?
A:首先是为了让字根编码规则和单字编码规则一致。其次,如果字根字是两码,但字根本身比较罕用,那么会浪费一个宝贵的二级简码码位。很多输入法会将另一个常用字设置成二简,而让字根字选重,或者通过其他方式为字根字增加一码。这个方式实际上却在事实上形成了新的重码。宇浩输入法直接在根源上解决了这个问题。

空格键的使用

在很多输入法软件中,空格键(以下用_表示)用来上屏首选字。

根据以上的学习内容,我们发现:「宇浩」的编码最长不超过4个字母。由于这个特性,我们在输入完编码后,不一定需要按空格键将字打上屏幕。

空格键只在以下情况需要使用:

  • 一个字的编码低于4位,需要按空格键上屏首选。比如「人」字,需要按Te_上屏。
  • 一个字的编码等于4位,且后面没有其他的字需要输入,则需要按空格键上屏首选。

以下情况,不需要使用空格键:

  • 一个字的编码等于4位,且有后续字符等待输入。我们不需要按空格键。只要直接输入下一个字的首码,这个字就会自动上屏。我们称之为「五码顶屏」。例如:我们打「霁雨」二字,「霁」字的编码是〔雨文{介下同八}・DPTi〕。输入b后,我们直接输入「雨」字的编码〔雨・Dyy〕,则「霁」字会自动上屏。

简码设置

学完了「宇浩」的单字编码,我们发现,「宇浩」的单字码长一般是2到4位之间。不少常用的字,码长是4位,比如字频第一的「的」字,编码为EWOd

一种科学的输入策略,应该使得常用字的码长更低,从而加快输入的速度。试想,如果输入「的」字,每次都要按EWOd四下按键,真是太浪费时间了。

形码对此的优化方式,就是设置简码,也就是给部分汉字设置更短的编码:比如,我们在输入「的」时,只要按上一个字母和空格键,就能实现输入。

简码的设置,应使得每一个字简码和全码的编码规则保持一致。当然,这也和文本环境有关。比如简体和繁体环境下,字频不同,简码也不相同。这里主要介绍的是基于典范白话文的简码设置。

一级简码字

一级简码字,又称一简字,指的是用一个字母为编码实现输入的汉字。「宇浩」中,有25个高频汉字设置为一简字,只要按下一个字母,加上空格,即可上屏。在我们的日常交流中,一简字大约占据了25%的使用频率。只需要按两个按键,可以有效提升输入速度。

一简字的编码,就是该字全码的第一个字母。

「我」全码为〔丿扌戈・QAGg〕,一级简码为Q。输入Q_即可实现上屏。
「的」全码为〔白{⼓同月}丶・EWOd〕,一级简码为E。输入E_即可实现上屏。

从A到Y排列,简体一级简码字分别是:

可对好不的一大到没是上中小回为这我得在人着了然出心

在字根图中,一简字就是每个字母方框的左上角的汉字。

宇浩的字根设计,使得最高频的汉字分布在最容易按的键上,比如:「的」在E上,「一」在F上,「了」在V上,「没」在I上,「不」在D上,「上」在K上。

二级简码字

二级简码字,又称二简字,指的是用两个字母为编码实现输入的汉字。「宇浩」中,有676个高频汉字设置为二简字,只要按下两个字母,加上空格,即可上屏。

二简字的编码,就是该字全码的前两个字母。使用「光华」方案举例:

「起」全码为〔走己・DBjk〕,二级简码为 DB。输入 DB_ 即可实现上屏。
「可」全码为〔丁口・ALvn〕,二级简码为 AL。输入 AL_ 即可实现上屏。

三级简码字

三级简码字,又称三简字,指的是用三个字母为编码实现输入的汉字,只要按下三个字母,加上空格,即可上屏。

三简字的编码,就是该字全码的前三个字母。这里不再举例。

注意到,三简字需要按四个按键才能上屏,同输入单字全码按键数一样,因此,三简字的设置主要为了腾出四码码位,实现避重。

三级简码字,可在打字时进行熟悉,不需要特别去记忆。

词语编码规则

除了设置简码,「宇浩」还将常用的词语,也编成4个字母的编码。这样可以降低每一个字的平均码长,提高打字速度。

「宇浩」的词语编码规则,分为三种情况。

两字词

两字词,取每个字全码的前两码即可。使用「光华」方案举例:

「人生」:「人」的编码为〔人・Tee〕,「生」的编码为〔生・Wgg〕。因此,「人生」的编码为〔人生・TeWg〕
「事情」:「事」的编码为〔{于下}口彐・ALXx〕,「情」的编码为〔心龶月・YHWy〕。因此,「事情」的编码为〔{于下}口心龶・ALYH〕

三字词

三字词,取前两字的第一码,和第三个字的前两码即可。使用「光华」方案举例:

「泡泡糖」:「泡」的编码为〔氵月巳・IWXk〕,「糖」的编码为〔米广又古・PUBD〕。因此,「泡泡糖」的编码为〔氵氵米广・IIPU〕
「星期三」:「星」的编码为〔日生・JWgr〕,「期」的编码为〔其月・DWyj〕,「三」的编码为〔三・Faa〕。因此,「星期三」的编码为〔日其三・JDFa〕

四字词及以上

四字词及以上,取前三字的第一码,和最后一个字的第一码即可。使用「光华」方案举例:

「狐假虎威」:「狐」的编码为〔犭瓜・RQuq〕,「假」的编码为〔亻尸二又・EBSB〕,「虎」的编码为〔虎・Muu〕,「威」的编码为〔戊一女・DFCn〕。因此,「狐假虎威」的编码为〔犭亻虎戊・REMD〕
「中华人民共和国」:这是一个七字词,所以我们只看前三字和最后一字「中」、「华」、「人」、「国」。「中」的编码为〔口丨・LMsv〕,「华」的编码为〔亻匕十・ERDi〕,「人」的编码为〔人・Te〕,「国」的编码为〔囗王丶・NGOd〕。因此,「中华人民共和国」的编码为〔口亻禾囗・LERN〕

词语输入的优缺点

用词语的方式进行输入,优点在于降低了每个字的平均码长。

试想「我们今天一起吃饭」这个句子,使用「光华」方案。

  • 如果打单字全码的话,需要按QAGgEpnTOViFDdiFi_DBjkLQViREBu
  • 如果打单字简码的话,需要按Q_EP_TOV_FG_F_DB_LQ_REBu
  • 如果打词语全码的话,需要按QAEPTOFGFiDBLQRE

可以看到,词语全码有效降低了按键的次数。

但是,词语输入也有其缺点,最主要的缺点包括:

  • 如果词库太小,不是每个词语都在词库中。很多时候还是需要打单字。
  • 如果词库太大,则会出现大量的重码,需要进行选择,破坏了形码输入的流畅性。
  • 你输入一个词语,却发现它并不在词库中,就需要删除后重新输入单字。让人感觉不悦。
  • 人工分词需要消耗额外的注意力。

因此,精简词库,熟悉词库,打单字和打词语相结合,是形码高手们的修炼之路。

进阶讨论

字形选取的标准

汉字具有多态性。同一个汉字,在不同的标准、不同的字体下,存在一定的差别。有些字形上的差别,通过 Unicode 的离散来实现。比如「户」「戶」「戸」三字,在 Unicode 里被安排在了不同的码位上,故而实现了分离。但是很多汉字的不同字形,却共用 Unicode 码位(这其实是 CJK 的初衷),那么这个字到底应该依照哪个标准来拆分,便成了问题。

宇浩输入法的规定是:

  • 每个字都有一种标准拆法,字形标准取自:The Unicode Standard, Version 15.0。各地区优先级降序为: GTHJKV,即陆、台、港、日、韩、越。也就是说,如果存在大陆提交的标准,就依照大陆标准。如果大陆没有提交标准,就按照台湾标准。依此类推。
  • 每个字都可能有若干兼容拆法,目的是兼容台湾、香港、大陆古籍的字形标准。比如「起=走己」(大陆标准)和「起=走巳」(台湾标准)兼收。

宇浩输入法的笔顺选取,依照大陆标准《GF 3003-1999 GB13000.1字符集汉字字序(笔画序)规范》。同时,也兼容台湾标准的笔顺。比如「攀=木乂乂木手」(大陆标准)和「攀=乂乂木木手」(台湾标准)兼收。

字根的内在属性

上面我们提到了宇浩输入法拆字规则的优先级。其实,在「字根最少」之上,还有一个隐藏的原则,也就是:字根的内在属性

何为字根的内在属性?其实就是指某一个字根区别于另一个字根的内在特点。

「吉」拆成「士口」而不是「土口」,这是因为「土」的下面一笔更长,而「士」的下面一笔更短。这是区别两个字根的本质原因和内在属性。

「内在属性」可以解释为什么有些字这样拆而不是那样拆,有些字为什么看上去违反了「字根最少」的原则。

「敝」拆为「丷巾八攵」而非「氺巾攵」,这看似违反了「字根最少」原则,但其实没有。注意到,「敝」字左下的笔画是撇不是提;在「氺」中,左下角的笔画是提不是撇。故而,「敝」字里并不存在「氺」字根。正因为如此,我们取四根「丷巾八攵」而非三根「氺巾攵」。

在这个章节,我们就详细讨论字根的内在属性,讨论某些字根在宇浩拆分中被分离或者被合并的原因,从而让某些字的拆分原因更加明确。

日曰之辨

不少输入法对与「日」「曰」两字的区分,比较复杂。大概有两种情况:

  • 有些是基于形状的,凡是长大于高的都为「曰」,凡是长短于高的都为「日」。但这个方法会跟随着字体的不同而不同,有时候不合字源,也不统一。例如:「書」字源于「聿者」,徐码中「書」下为「曰」,但「者」下为「日」,取码不统一。「曹」古字为「东东口」。在徐码中,「曹」下为「日」,不符合字源。
  • 另外一种区分方法是基于字源。也就是说:凡是在古文中作「口」形,之后隶变为「曰」形或「甘」形的字,都作「曰」。但这个方法对方一般的使用者难度太大,且分析字源会有疏漏之处,不应用于输入法。

我们必须注意到,在汉字中,存在「日曰」对立的字形,只有三组,分别为:「日曰」、「汨汩」、「曶㫚」。在其他的情况下,不存在对立,也就不存在混淆问题。

因此,我基于实用主义原则,对这两个字根不多加以区分,而采取更简单的方法。即:除了上述三组对立情况外,全部取「日」根。换句话说,「曰」根只需要在对立情况下才会使用,包括:「曰」「汩」「㫚」三个字。

这样一来,可以显著降低使用者的记忆和学习负担。

勹𠂊之辨

「旬」的外框「勹」,同「敖」左下的「𠂊」都是撇加横折钩。宇浩输入法不做区分。

这里对「点」的拆分作出解释:

  • 单点和捺视为一个字根。
  • 相重叠的两点,即「头」「冬」中的部分,同「二」。
  • 左对点「冫」和右对点「飞右」,同「二」。故而「兆」拆为「儿二二」。
  • 下对点「八」在一个大码。
  • 其他对点「丷」「䒑」「⺦」「リ」在一个大码。
  • 所有三点都在一个大码。
  • 所有四点都在一个大码。

「为」「卵」等字的两点和「冬」下的两点不同,相隔太远,且被半包围或全包围分割,故而不认定为「两点」。

人八入之辨

「人」「八」「入」三字易混,这里做出区分:

  • 凡左撇不低于右捺,作「人」。
  • 凡左撇低于右捺,作「入」。
  • 凡左撇右捺分离,或者中间被其他笔画隔开,作「八」。

口中无整画

口(音kǒu),囗(音wéi)。这两个根如何区分?

答案是,如果方框里有完整的笔画,用「囗」wéi。否则一律用「口」kǒu

「国」字中,有完整的笔画,故而必须用「囗」wéi。 「中」字中,虽然「⼁」穿「口」而过,但并未被完全包含在「口」中。由于「口」中没有完整的笔画,故而用「口」kǒu

此规定也适用于另外两个包含「口」的字根:

  • 「古」下的「口」中如果包含完整的笔画,应该拆如「十囗」。例如:「鄙」左下方的「口」中有「口」,故而应该拆成「口十囗口阝」。
  • 「合」下的「口」中如果包含完整的笔画,应该拆如「人一囗」。例如:「會」中間的「口」中有「小」,故而应该拆成「人一𫩏丷日」。

汉字的拆分禁手

拆分之「禁手」,指的是无论任何时候都不应当出现一些拆分情形。它高于一切拆分规则。一旦某一个拆分候选中出现了「禁手」,则直接淘汰。禁手包括:散件不分割、竖向不包夹、横间不穿心。

散件不分割

有一部分字根,本身存在离散的部件,比如「戈」字右上的点、「犬」字的右上的点、「三」字的三个横等等。为了保证拆字的直观,保证检字(尤其是大字集下)的便捷性,我们需要对字根的连续性做出要求,并将它认定为字根的内在属性。

字根的连续性定义如下:

一个字根的离散部件,不可被全包围结构或半包围结构分割。被分割的两个部件不得视为一个字根。

「为」字的两点不可以被视为字根「两点」,因为它们被半包围结构分割。
「曵」字不拆「囗戈」而拆成「电丿丶」,因为「戈」字右上方的点被全包围结构分割。

竖向不包夹

不少字根中存在若干分散的部件,比如:

  • 「二」和「三」中的横画是分离的。
  • 「合」分为了「一」「一」「口」三个部分。
  • 「儿」分为了「丿」「乚」两个部分。

这给了它们包夹其他字根的可能。如「亘」可看成「二」包夹「日」。

为了防止拆分不直观,我们做出规定,一个字根可以横向包夹,但不能纵向包夹

卿 = 卯彐厶
胤 = 儿幺月
亘 = 一日一
僵 = 亻一田一田一

这是因为,汉字的左右对称多于上下对称。左右包夹是可预测的,但上下包夹往往不可预测,必须要观察到最下方。比如,某些输入法设置了「衣」字根,但「亠」和「𧘇」的出现并不总是成对的,必须看到最下方才能正确判断。

横间不穿心

为了使拆分更加直观,符合笔顺,防止字根交叉粘连,我们规定:

「工土士干千禾キ王壬龶丰末未生古矢缶早羊虫」等字根不允许在「一一」间穿插其他字根。

这个规定在常用字中比较少用。列举如下:

  • 「再」不拆「王冂」,而拆「一冂土」
  • 「垂」不拆「壬龷」,而拆「千龷一」
  • 「夀」不拆「龶乛口口寸」,而拆「二乛口丄口寸」
  • 「禹」不拆「丿虫冂」,而拆「丿口冂<丄丶>」

脚注

  1. 当然,汉字不是完全可以量化的,不同字形下,也会出现不同的拆分可能。除了良好的定义外,有时候比例原则也很重要。尤其在大字集上,追求单一拆分方法会扭曲汉字直观性,不能兼顾不同字形,让使用者需要大量尝试才能找到想要的字,这违背了大字集检字的初衷。因此,对于大字集,我也会设置兼容拆分和容错码。