殷知磊, 張鐘澍, 肖躍先, 薛 松
(成都信息工程學院計算機學院,四川成都 610225)
目前ARM 板已經普遍應用于各種手機、玩具等電器產品,特別是嵌入式Linux技術與ARM的結合,以其開放的源代碼、低廉的價格、方便的開發環境受到了許多開發廠家的青睞。隨著智能手持設備的快速發展,漢字的輸入輸出己經成為很多智能手持設備進行人機交互不可缺少的部分,其中以手機中漢字輸入使用最為廣泛。
目前已有的漢字庫生成方法耗費人力物力較大、開發周期長、漢字采集不夠完整、輸入法對漢字庫進行索引時速度較慢等問題;已有的漢字庫的索引原理在輸入法根據拼音索引漢字的時候需要大量的CPU時間,這顯然不適合嵌入式設備的要求。文中介紹的漢字庫設計結構,可以在利用簡單的設備,需要短時間內即可生成一個可以供中文全拼輸入法使用的漢字庫,特別適用于在項目周期短,又要求中文輸入法支持的項目開發。
文中介紹的漢字庫生成法屬于支持中文全拼輸入法的底層開發,為利用Qt/Embedded開發的輸入法提供了漢字索引支持。生成的漢字庫也使全拼輸入法根據拼音索引漢字的效率比已有的漢字庫有所提高。
傳統拼音輸入法的設計思想是通過用戶的按鍵操作得到一組數字組合,由這個數字組合得到可能出現的拼音組合(通常一組數字組合對應多組拼音組合,如“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所示。

圖2 漢字庫結構示意圖
在Windows環境下可以利用豐富的資源進行方便的編程,取得漢字信息和生成既定格式的漢字庫,但只有在ARM-Linux環境下才可以正確地確定哪些漢字無法正常顯示(即非法漢字)。所以漢字庫的創建流程分為在Windows環境下和在ARM-Linux環境下的處理。漢字庫的生成總體流程如圖3所示。

圖3 全拼輸入法漢字庫生成流程圖
生成全拼輸入法漢字庫一共分為5個步驟:漢字采集;生成初級漢字庫;確定QT/Embedded環境中無法正常顯示的非法漢字;剔除非法漢字和重新生成漢字庫。
全拼輸入法漢字庫生成的第一步是盡可能地取到并記錄現有的所有漢字的信息。在文中,將系統需要的輸入法設置為“中文全拼輸入法”,用程序模擬鍵盤按鍵信息輸入,可以將拼音信息和中文全拼輸入法輸出的漢字信息保存在一個文件中。直到將所有的漢語拼音信息和漢字信息記錄完成[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 漢字采集保存的格式
取得拼音和對應的漢字信息后,這些信息無法使中文輸入法方便地使用,因此需要將這些信息加工為指定格式的漢字和拼音對應關系。
初級漢字庫的生成過程以上述漢字采集文件為輸入,可以在這個過程中選擇生成Unicode編碼形式或者ANSI編碼形式。選擇哪種編碼形式,由用戶根據所有的ARM-Linux系統及開發的輸入法的用途來決定。這里介紹的是選擇加工生成ANSI編碼形式的初級漢字庫文件。
在生成初級漢字庫之前,需要按照既定的漢字庫格式初始化漢字庫,即建立一個和既定格式相同的空文件,然后將該空漢字庫文件進行填充。
填充空漢字庫時,將采集漢字生成的漢字文件信息按行分解開來成為漢字信息單元。在每個單元的開頭有一個組號,找到第一個組號為“0”的單元時,將該組拼音填入到第一個拼音入口的拼音信息中,記下該漢字庫中正文的位置,將位置信息添加到拼音入口的對應結構。然后將該組的所有漢字部分添加到漢字庫中,并做好漢字個數的記錄,最后將漢字個數記錄寫入漢字庫拼音入口的字數統計處。
將這一組的漢字和拼音信息提取并寫入漢字庫以后,再判斷下一組的漢字信息,此時如果組號不為“0”,則繼續添加本組漢字信息到漢字庫的正文部分,并將漢字字數統計信息進行更新。
依照此操作,找到下一組組號為“0”的漢字信息單元,將拼音入口的序號向后移動一個,繼續以上的操作。直到找到漢字采集文件的最后一個漢字。這樣即可將已經按照既定格式初始化的空漢字庫填充完畢,初級漢字庫生成完成。
拼音和漢字對應關系建立完成以后,要確定這些漢字必須可以在目標系統ARM-Linux系統中正常顯示。內碼就是漢字的編碼在機器內的表示,就是通常的GBK,BIG5等,內碼轉換就是在不同編碼的字符集間建立一種對應關系。如果本地機器支持的編碼方式不一樣或者支持的字符集不相同,在顯示文檔時就會出現亂碼的情況[2]。由于Windows系統和ARM-Linux系統中的內碼有差別,所以需要在目標系統中對已經包含的所有漢字進行判斷,首先確定無法在目標系統中顯示的漢字,即非法漢字。
初級漢字庫建立以后,在ARM-Linux系統中,按照輸入法可以訪問的形式,將漢字庫中的拼音和對應漢字自動遍歷并在ARM-Linux系統顯示出來,可以看出有些在Windows系統中的ANSI編碼形式的漢字無法在ARMLinux系統中正常顯示出來,這些無法正常顯示的漢字的十六進制編碼為“EF BF BD”[4]。過程需將包括這些信息的拼音和漢字信息保存成為一個新的文檔。文檔的結構是以拼音為單位,一個拼音后邊跟一個空格然后是這個拼音對應的所有的漢字。至此,文檔中包括的所有的拼音信息和合法或者非法的漢字,無法正常顯示的漢字已經被標識完畢。
確定目標系統中的非法漢字后,需要用一種方便的方法將這部分漢字剔除,這就是剔除非法漢字部分需要做的工作。剔除非法漢字,可以將所有非法漢字一次性剔除而不會影響正常漢字。
由于非法漢字的編碼已經確定,將這個編碼的漢字剔出就較容易做到。在遍歷上一步驟生成的文件時,按照順序的遍歷方法及拼音順序查找,遇到編碼為“EF BF BD”的漢字,自動進行剔除。
剔除非法漢字的同時,為了使下一步生成真正ARM-Linux可用的漢字庫,應將剔除非法漢字后的文件按照采集漢字后生成的文件格式進行編輯。
剔除非法漢字后,留下的漢字都是可以在ARM-Linux下正常使用的漢字。在剔除無法正常顯示的漢字的同時,將文件的格式也進行了調整,此時可以將文件視為采集漢字時生成的文件格式,如圖4所示。
重新生成漢字庫的過程以已經剔除非法漢字以后的文件為輸入,選擇生成Unicode編碼形式或者ANSI編碼形式。在加工過程中,還需要根據文件中的拼音組信息,更新對應的拼音入口的信息,比如剔除一些無正確漢字對應的拼音組。生成最終可以在目標系統中正常使用的漢字庫,此時的全拼輸入法漢字庫生成完成。
文中介紹的漢字采集所采用的方法與一般的漢字采集對應時間如表1所示。

表1 漢字采集的時間比較
除了采集漢字之外的其他步驟,都是對很小的文件進行處理,費時很小,除了采集漢字以外的步驟,可以在一個小時內完成,故在整個漢字庫生成的過程中不做討論。
整個生成漢字庫的過程中,將從漢字采集文件中讀出的漢字提取出來后,將其編碼更改為指定編碼方式之后再存入漢字庫中。這樣就可以對漢字編碼形式進行控制。
由于初級漢字庫生成后,是在ARM-Linux系統中進行讀取漢字庫信息,然后由ARM-Linux系統對漢字庫中的漢字進行逐字標識,所以可以保證漢字庫中的漢字都是可以在ARM-Linux系統正常顯示的漢字。
中文輸入法在訪問漢字庫時只需查找漢字庫的文件頭,在總數為436的拼音入口中匹配拼音,直接得到拼音對應的首個漢字的地址,然后進行漢字的讀取即可。完全可以滿足用戶手動輸入拼音時,對當前拼音對應漢字的顯示更新速度要求。整個訪問漢字庫的方法簡單易行。
全拼輸入法被初始化的時候,首先需要判斷漢字庫是否已經存放在指定的位置,并判斷漢字庫的文件頭部分是否為已經定義的漢字庫文件標識符。如果文件頭匹配,則說明漢字庫已經存在而且可用。
用戶輸入正確的拼音后,輸入法開始在漢字庫的文件頭中查找該拼音的拼音入口結構。找到拼音入口的拼音部分和用戶輸入的拼音匹配,則返回該拼音入口的漢字存放的起始位置,然后從文件的這個位置開始讀取漢字。讀取漢字的個數則由該拼音入口的拼音對應漢字個數來確定。此時,對應用戶輸入的拼音的漢字已經全部讀出。將這些漢字顯示在漢字框中,用戶即可以按照自己的需要選擇正確的漢字[6、7]。
提出了一種可以適合一般的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.