基于程序框架Qt的嵌入式系统汉字库设计与实现
2010-09-21殷知磊张钟澍肖跃先
殷知磊, 张钟澍, 肖跃先, 薛 松
(成都信息工程学院计算机学院,四川成都 610225)
1 引言
1.1 研究背景
目前ARM 板已经普遍应用于各种手机、玩具等电器产品,特别是嵌入式Linux技术与ARM的结合,以其开放的源代码、低廉的价格、方便的开发环境受到了许多开发厂家的青睐。随着智能手持设备的快速发展,汉字的输入输出己经成为很多智能手持设备进行人机交互不可缺少的部分,其中以手机中汉字输入使用最为广泛。
目前已有的汉字库生成方法耗费人力物力较大、开发周期长、汉字采集不够完整、输入法对汉字库进行索引时速度较慢等问题;已有的汉字库的索引原理在输入法根据拼音索引汉字的时候需要大量的CPU时间,这显然不适合嵌入式设备的要求。文中介绍的汉字库设计结构,可以在利用简单的设备,需要短时间内即可生成一个可以供中文全拼输入法使用的汉字库,特别适用于在项目周期短,又要求中文输入法支持的项目开发。
文中介绍的汉字库生成法属于支持中文全拼输入法的底层开发,为利用Qt/Embedded开发的输入法提供了汉字索引支持。生成的汉字库也使全拼输入法根据拼音索引汉字的效率比已有的汉字库有所提高。
1.2 几种常见的汉字库设计
传统拼音输入法的设计思想是通过用户的按键操作得到一组数字组合,由这个数字组合得到可能出现的拼音组合(通常一组数字组合对应多组拼音组合,如“426”这组数字组合就对应“han”、“hao”、“gan”、“gao”这4组拼音组合),而每组拼音组合对应了1组同音汉字组(比如“hao”对应了“好”、“号”、“毫”等),这种结构当中实现的是1个二级对应表。这个二级对应表一般按照数组或者树型结构进行组织。
(1)数在汉字中拼音共有400多个,可以将每个拼音定义为一个数组,数组的成员包括不考虑声调时读音相同的汉字。在输入法中建立通过一个结构体建立一个数字键,拼音组合一同拼音汉字组的联系,输入法剩下的工作都是通过搜索这样的结构体来完成匹配过程,如图1所示。这个过程需要大量的CPU时间,这对嵌入式设备而言是不利的。
(2)键树的实现方法
设有字符集的集合{hao,hai,li,lan,cui,wang,tian,tang,liu,chen},按首字母将其分解为{hao,hai}、{li,lan}、{cui、chen}、{wang}、{tian、tang},对于关键字个数大1的集合需要再按第2个字母进行分解。显然,按此方法分解的集合很容易生成一棵有序树,即同一层的兄弟结点之间所含的字符从左至右有序。
图1 用数组方法创建的汉字库示意图
从根结点到某子结点或叶子结点的一条路径构成一个关键字,对于某结点的子结点来说,它是有序的,即从左至右由小到大排列,这样将有利于构造和检索,但是在图中每个结点包含的域是不定的,这在构造时并不利于生成拼音树。
若关键字仅由英文字母组成时,树中每个结点可由27个指针域组成。双链树用在拼音输入时,不足以描述拼音对应的字库信息以及兄弟结点和父结点的关系,而Trie树包含27个域,其中26个对应于26个字母,事实上,最长的拼音也只有6个字母,即构造的树深度为6,标准的Trie树中,每个结点包含27个域,其内存占用空间相当大,因此不适合在拼音输入法中直接使用键树的方法[2]。
2 ARM-Linux系统中文全拼输入法汉字库的设计
优秀的汉字库应该在保证中文输入法正确的前提下,使中文输入法的设计与实现更加简单和高效。根据中文全拼输入法的特点,汉字库中应包含以下内容:汉字库文件标识,输入法所在系统使用的编码方式支持的所有汉字,输入法所在系统包含的汉字对应的汉字拼音信息,以及这些拼音信息对应的汉字的位置,以及每个拼音对应的汉字的个数。
对于以上需求,设计中文全拼输入法汉字库的结构如下:汉字库的文件头部分和汉字库正文部分。汉字库的文件头部分包括汉字库标识、汉字库拼音索引和拼音入口结构体,拼音入口的结构又包括拼音、拼音对应的汉字以及拼音对应的第一个汉字在汉字库中的位置。汉字库的正文部分包括所有拼音对应的汉字。汉字库的结构如图2所示。
图2 汉字库结构示意图
3 中文全拼输入法汉字库的创建流程
在Windows环境下可以利用丰富的资源进行方便的编程,取得汉字信息和生成既定格式的汉字库,但只有在ARM-Linux环境下才可以正确地确定哪些汉字无法正常显示(即非法汉字)。所以汉字库的创建流程分为在Windows环境下和在ARM-Linux环境下的处理。汉字库的生成总体流程如图3所示。
图3 全拼输入法汉字库生成流程图
生成全拼输入法汉字库一共分为5个步骤:汉字采集;生成初级汉字库;确定QT/Embedded环境中无法正常显示的非法汉字;剔除非法汉字和重新生成汉字库。
3.1 汉字和拼音信息采集
全拼输入法汉字库生成的第一步是尽可能地取到并记录现有的所有汉字的信息。在文中,将系统需要的输入法设置为“中文全拼输入法”,用程序模拟键盘按键信息输入,可以将拼音信息和中文全拼输入法输出的汉字信息保存在一个文件中。直到将所有的汉语拼音信息和汉字信息记录完成[5]。
在模拟键盘输入采集汉字的过程中,有两个指标比较重要,即输入次数和输入正确率。输入次数是指为了完成某些功能需要模拟的键盘输入次数。输入正确率是指为了完成某些功能,在输入的过程中正确的输入在所有输入中所占的比例。
在模拟键盘输入的过程中,假设输入法的拼音输入完成后选择汉字和将汉字返回给上层窗体的操作是一定的。普通的遍历输入算法一般按照顺序输入英文字母作为拼音,如果组合成功则显示并记录汉字,否则放弃输入自动跳转至下一组输入。那么,取得所有汉字需要输入键盘键码的次数N和最大拼音组合的长度n之间的关系为:
N=26+262+…+26n(n>0) (n为拼音组合的最大长度)
输入正确率 R,即输入的正确拼音组合数Ri占所有输入拼音组合Ra中的比例为:
其中,Ri为正确拼音组合数,Ra为所有输入拼音组合数。
如果以汉语拼音最长为6个字母长度(如:“装”的汉语拼音为zhuang)计算,则需要键盘的处理321272406次。在汉语言中,正确的拼音组合数为436个。不难算出,这种方法的输入正确率仅为0.0001357%。在主频为2.0GHz的普通PC机上处理如此多的键盘输入,经两次实验测得向缓存输入汉字和记录汉字到指定文件的总共时间约为190小时,共采集了456个拼音,这些拼音共记录61609个汉字。
文中在汉字采集的过程中采用一种新方法,即利用汉语拼音的特点,将汉语拼音中的声母和韵母进行组合输入。输入拼音时将所有的声母作为声母源单元Sc,将所有韵母都作为韵母输入源单元Sv,每次输入的拼音都为一个声母源单元和一个韵母源单元的组合,这样可以大大减少输入的次数,提高输入正确率。
以下就输入次数和输入正确率的计算进行分析。
由于在每次输入声母之后都需要输入一个韵母进行匹配,所以韵母源单元的输入是必不可少的,所有韵母源单元的输入次数 Nt为:
Sv-1为韵母源单元中只需输入一次的韵母个数;Sv-2为韵母源单元中需要输入两次的韵母个数;Sv-3为韵母源单元中需要输入三次的韵母个数;Sv-4为韵母源单元中需要输入四次的韵母个数。
组合拼音模拟输入算法的输入键盘键码的次数N
Sc-1为声母源单元中只需输入一次的声母个数;Sc-2为声母源单元中需要输入两次的声母个数。
汉语言中声母的个数为23个,其中双字母声母为3个,其余为单字母声母;韵母个数为35个,其中单字母韵母6个,双字母韵母13个,三字母韵母12个,四字母韵母4个,由以上公式可以计算出需要输入键盘键码的次数为2268次。
由公式(1)可以计算出采用声母韵母组合输入拼音的输入正确率提高到19.2239%,这比无序的输入字母进行汉字采集提高了1415倍。在主频为2.0GHz的普通PC机上处理如此多的键盘输入,经多次实验测得向缓存输入汉字和记录汉字到指定文件的总共时间约为5.5小时,共采集了456个拼音,这些拼音共记录了61609个汉字。
由分析可知,在采集汉字的过程中,使用声母和韵母组合后采集汉字的方法提高输入的正确率,大大减少了采集汉字信息的输入次数,是一种优秀的汉字采集方法。
汉字信息采集的时候,存储拼音和汉字信息的格式如下:文件的每一行开头的本行汉字的拼音组标号,后边为汉字和拼音元,汉字拼音元为汉字加拼音的格式,如“啊:a0”,“啊”为汉字,“a”为拼音,“0”是“a”这个拼音在使用的输入法中对应的序号。具体存储格式如图4所示。
图4 汉字采集保存的格式
3.2 初级汉字库生成
取得拼音和对应的汉字信息后,这些信息无法使中文输入法方便地使用,因此需要将这些信息加工为指定格式的汉字和拼音对应关系。
初级汉字库的生成过程以上述汉字采集文件为输入,可以在这个过程中选择生成Unicode编码形式或者ANSI编码形式。选择哪种编码形式,由用户根据所有的ARM-Linux系统及开发的输入法的用途来决定。这里介绍的是选择加工生成ANSI编码形式的初级汉字库文件。
在生成初级汉字库之前,需要按照既定的汉字库格式初始化汉字库,即建立一个和既定格式相同的空文件,然后将该空汉字库文件进行填充。
填充空汉字库时,将采集汉字生成的汉字文件信息按行分解开来成为汉字信息单元。在每个单元的开头有一个组号,找到第一个组号为“0”的单元时,将该组拼音填入到第一个拼音入口的拼音信息中,记下该汉字库中正文的位置,将位置信息添加到拼音入口的对应结构。然后将该组的所有汉字部分添加到汉字库中,并做好汉字个数的记录,最后将汉字个数记录写入汉字库拼音入口的字数统计处。
将这一组的汉字和拼音信息提取并写入汉字库以后,再判断下一组的汉字信息,此时如果组号不为“0”,则继续添加本组汉字信息到汉字库的正文部分,并将汉字字数统计信息进行更新。
依照此操作,找到下一组组号为“0”的汉字信息单元,将拼音入口的序号向后移动一个,继续以上的操作。直到找到汉字采集文件的最后一个汉字。这样即可将已经按照既定格式初始化的空汉字库填充完毕,初级汉字库生成完成。
3.3 确定汉字库中无法在目标系统正常显示汉字
拼音和汉字对应关系建立完成以后,要确定这些汉字必须可以在目标系统ARM-Linux系统中正常显示。内码就是汉字的编码在机器内的表示,就是通常的GBK,BIG5等,内码转换就是在不同编码的字符集间建立一种对应关系。如果本地机器支持的编码方式不一样或者支持的字符集不相同,在显示文档时就会出现乱码的情况[2]。由于Windows系统和ARM-Linux系统中的内码有差别,所以需要在目标系统中对已经包含的所有汉字进行判断,首先确定无法在目标系统中显示的汉字,即非法汉字。
初级汉字库建立以后,在ARM-Linux系统中,按照输入法可以访问的形式,将汉字库中的拼音和对应汉字自动遍历并在ARM-Linux系统显示出来,可以看出有些在Windows系统中的ANSI编码形式的汉字无法在ARMLinux系统中正常显示出来,这些无法正常显示的汉字的十六进制编码为“EF BF BD”[4]。过程需将包括这些信息的拼音和汉字信息保存成为一个新的文档。文档的结构是以拼音为单位,一个拼音后边跟一个空格然后是这个拼音对应的所有的汉字。至此,文档中包括的所有的拼音信息和合法或者非法的汉字,无法正常显示的汉字已经被标识完毕。
3.4 剔除无法显示汉字
确定目标系统中的非法汉字后,需要用一种方便的方法将这部分汉字剔除,这就是剔除非法汉字部分需要做的工作。剔除非法汉字,可以将所有非法汉字一次性剔除而不会影响正常汉字。
由于非法汉字的编码已经确定,将这个编码的汉字剔出就较容易做到。在遍历上一步骤生成的文件时,按照顺序的遍历方法及拼音顺序查找,遇到编码为“EF BF BD”的汉字,自动进行剔除。
剔除非法汉字的同时,为了使下一步生成真正ARM-Linux可用的汉字库,应将剔除非法汉字后的文件按照采集汉字后生成的文件格式进行编辑。
3.5 重新生成汉字库
剔除非法汉字后,留下的汉字都是可以在ARM-Linux下正常使用的汉字。在剔除无法正常显示的汉字的同时,将文件的格式也进行了调整,此时可以将文件视为采集汉字时生成的文件格式,如图4所示。
重新生成汉字库的过程以已经剔除非法汉字以后的文件为输入,选择生成Unicode编码形式或者ANSI编码形式。在加工过程中,还需要根据文件中的拼音组信息,更新对应的拼音入口的信息,比如剔除一些无正确汉字对应的拼音组。生成最终可以在目标系统中正常使用的汉字库,此时的全拼输入法汉字库生成完成。
4 汉字库的使用效果分析
文中介绍的汉字采集所采用的方法与一般的汉字采集对应时间如表1所示。
表1 汉字采集的时间比较
除了采集汉字之外的其他步骤,都是对很小的文件进行处理,费时很小,除了采集汉字以外的步骤,可以在一个小时内完成,故在整个汉字库生成的过程中不做讨论。
整个生成汉字库的过程中,将从汉字采集文件中读出的汉字提取出来后,将其编码更改为指定编码方式之后再存入汉字库中。这样就可以对汉字编码形式进行控制。
由于初级汉字库生成后,是在ARM-Linux系统中进行读取汉字库信息,然后由ARM-Linux系统对汉字库中的汉字进行逐字标识,所以可以保证汉字库中的汉字都是可以在ARM-Linux系统正常显示的汉字。
中文输入法在访问汉字库时只需查找汉字库的文件头,在总数为436的拼音入口中匹配拼音,直接得到拼音对应的首个汉字的地址,然后进行汉字的读取即可。完全可以满足用户手动输入拼音时,对当前拼音对应汉字的显示更新速度要求。整个访问汉字库的方法简单易行。
全拼输入法被初始化的时候,首先需要判断汉字库是否已经存放在指定的位置,并判断汉字库的文件头部分是否为已经定义的汉字库文件标识符。如果文件头匹配,则说明汉字库已经存在而且可用。
用户输入正确的拼音后,输入法开始在汉字库的文件头中查找该拼音的拼音入口结构。找到拼音入口的拼音部分和用户输入的拼音匹配,则返回该拼音入口的汉字存放的起始位置,然后从文件的这个位置开始读取汉字。读取汉字的个数则由该拼音入口的拼音对应汉字个数来确定。此时,对应用户输入的拼音的汉字已经全部读出。将这些汉字显示在汉字框中,用户即可以按照自己的需要选择正确的汉字[6、7]。
5 结束语
提出了一种可以适合一般的Qt/Embedded的中文全拼输入法汉字库生成方法,使用该方法生成的汉字库结构合理,对Linux系统中可显示的汉字支持率可达到100%,输入法访问方便,而且整个生成时间只用了约6.5小时。这比传统的汉字库组织生成方法有了很大的提高,是一种优秀的汉字库快速生成方法。
目前,该方法已经运用在我国自主研发的(L-S)波段卫星移动通信便携式终端(国家863项目)中,以此汉字库为基础的中文输入法运行正常。由于该方法生成汉字库迅速,在短时间内生成了可供(L-S)波段卫星移动通信便携式终端使用的汉字库,为其提供了中文输入法的支持,也为我国卫星通信争夺(L-S)波段使用权的终端开发过程中节约了宝贵的时间。
经过理论分析和实践验证,文中的全拼输入法汉字库设计以及汉字库的生成方法非常适合ARM-Linux系统的全拼中文输入法使用。
[1] 李向阳,曾旖,奚大顺.在UC/GUI中实现汉字显示[J].单片机与嵌入式系统应用,2005,(5).
[2] 童学才.基于MiniGUI的嵌入式系统中文输入法设计[D].武汉:武汉科技大学,2007.
[3] 乔建良,赵增建.谈谈手机的中文输入法[J].现代通信,2004,(3).
[4] 廖红玉,刘会平,陈晓云.在C#中实现对乱码的正确显示[J].微计算机应用,2005,(4).
[5] 陈小康,江颉.支持中文编码和中文输入的WML编码器的设计与实现[J].计算机工程与应用,2002,(2).
[6] 钱斌.RedHat Linux中文输入法补充[J].计算机应用文摘,2001,(12).
[7] 罗帆.Linux下的中文输入法[J].计算机应用文摘,2003,(7).
[8] 热依曼.吐尔逊,吾守尔.斯拉木,努尔麦麦提.多文种手机混合输入/输出技术及实现[J].计算机工程与科学,2006,28(4):103-104.