殷知磊, 張鐘澍, 肖躍先, 薛 松
(成都信息工程學(xué)院計(jì)算機(jī)學(xué)院,四川成都 610225)
目前ARM 板已經(jīng)普遍應(yīng)用于各種手機(jī)、玩具等電器產(chǎn)品,特別是嵌入式Linux技術(shù)與ARM的結(jié)合,以其開放的源代碼、低廉的價(jià)格、方便的開發(fā)環(huán)境受到了許多開發(fā)廠家的青睞。隨著智能手持設(shè)備的快速發(fā)展,漢字的輸入輸出己經(jīng)成為很多智能手持設(shè)備進(jìn)行人機(jī)交互不可缺少的部分,其中以手機(jī)中漢字輸入使用最為廣泛。
目前已有的漢字庫生成方法耗費(fèi)人力物力較大、開發(fā)周期長、漢字采集不夠完整、輸入法對(duì)漢字庫進(jìn)行索引時(shí)速度較慢等問題;已有的漢字庫的索引原理在輸入法根據(jù)拼音索引漢字的時(shí)候需要大量的CPU時(shí)間,這顯然不適合嵌入式設(shè)備的要求。文中介紹的漢字庫設(shè)計(jì)結(jié)構(gòu),可以在利用簡單的設(shè)備,需要短時(shí)間內(nèi)即可生成一個(gè)可以供中文全拼輸入法使用的漢字庫,特別適用于在項(xiàng)目周期短,又要求中文輸入法支持的項(xiàng)目開發(fā)。
文中介紹的漢字庫生成法屬于支持中文全拼輸入法的底層開發(fā),為利用Qt/Embedded開發(fā)的輸入法提供了漢字索引支持。生成的漢字庫也使全拼輸入法根據(jù)拼音索引漢字的效率比已有的漢字庫有所提高。
傳統(tǒng)拼音輸入法的設(shè)計(jì)思想是通過用戶的按鍵操作得到一組數(shù)字組合,由這個(gè)數(shù)字組合得到可能出現(xiàn)的拼音組合(通常一組數(shù)字組合對(duì)應(yīng)多組拼音組合,如“426”這組數(shù)字組合就對(duì)應(yīng)“han”、“hao”、“gan”、“gao”這4組拼音組合),而每組拼音組合對(duì)應(yīng)了1組同音漢字組(比如“hao”對(duì)應(yīng)了“好”、“號(hào)”、“毫”等),這種結(jié)構(gòu)當(dāng)中實(shí)現(xiàn)的是1個(gè)二級(jí)對(duì)應(yīng)表。這個(gè)二級(jí)對(duì)應(yīng)表一般按照數(shù)組或者樹型結(jié)構(gòu)進(jìn)行組織。
(1)數(shù)在漢字中拼音共有400多個(gè),可以將每個(gè)拼音定義為一個(gè)數(shù)組,數(shù)組的成員包括不考慮聲調(diào)時(shí)讀音相同的漢字。在輸入法中建立通過一個(gè)結(jié)構(gòu)體建立一個(gè)數(shù)字鍵,拼音組合一同拼音漢字組的聯(lián)系,輸入法剩下的工作都是通過搜索這樣的結(jié)構(gòu)體來完成匹配過程,如圖1所示。這個(gè)過程需要大量的CPU時(shí)間,這對(duì)嵌入式設(shè)備而言是不利的。
(2)鍵樹的實(shí)現(xiàn)方法
設(shè)有字符集的集合{hao,hai,li,lan,cui,wang,tian,tang,liu,chen},按首字母將其分解為{hao,hai}、{li,lan}、{cui、chen}、{wang}、{tian、tang},對(duì)于關(guān)鍵字個(gè)數(shù)大1的集合需要再按第2個(gè)字母進(jìn)行分解。顯然,按此方法分解的集合很容易生成一棵有序樹,即同一層的兄弟結(jié)點(diǎn)之間所含的字符從左至右有序。
圖1 用數(shù)組方法創(chuàng)建的漢字庫示意圖
從根結(jié)點(diǎn)到某子結(jié)點(diǎn)或葉子結(jié)點(diǎn)的一條路徑構(gòu)成一個(gè)關(guān)鍵字,對(duì)于某結(jié)點(diǎn)的子結(jié)點(diǎn)來說,它是有序的,即從左至右由小到大排列,這樣將有利于構(gòu)造和檢索,但是在圖中每個(gè)結(jié)點(diǎn)包含的域是不定的,這在構(gòu)造時(shí)并不利于生成拼音樹。
若關(guān)鍵字僅由英文字母組成時(shí),樹中每個(gè)結(jié)點(diǎn)可由27個(gè)指針域組成。雙鏈樹用在拼音輸入時(shí),不足以描述拼音對(duì)應(yīng)的字庫信息以及兄弟結(jié)點(diǎn)和父結(jié)點(diǎn)的關(guān)系,而Trie樹包含27個(gè)域,其中26個(gè)對(duì)應(yīng)于26個(gè)字母,事實(shí)上,最長的拼音也只有6個(gè)字母,即構(gòu)造的樹深度為6,標(biāo)準(zhǔn)的Trie樹中,每個(gè)結(jié)點(diǎn)包含27個(gè)域,其內(nèi)存占用空間相當(dāng)大,因此不適合在拼音輸入法中直接使用鍵樹的方法[2]。
優(yōu)秀的漢字庫應(yīng)該在保證中文輸入法正確的前提下,使中文輸入法的設(shè)計(jì)與實(shí)現(xiàn)更加簡單和高效。根據(jù)中文全拼輸入法的特點(diǎn),漢字庫中應(yīng)包含以下內(nèi)容:漢字庫文件標(biāo)識(shí),輸入法所在系統(tǒng)使用的編碼方式支持的所有漢字,輸入法所在系統(tǒng)包含的漢字對(duì)應(yīng)的漢字拼音信息,以及這些拼音信息對(duì)應(yīng)的漢字的位置,以及每個(gè)拼音對(duì)應(yīng)的漢字的個(gè)數(shù)。
對(duì)于以上需求,設(shè)計(jì)中文全拼輸入法漢字庫的結(jié)構(gòu)如下:漢字庫的文件頭部分和漢字庫正文部分。漢字庫的文件頭部分包括漢字庫標(biāo)識(shí)、漢字庫拼音索引和拼音入口結(jié)構(gòu)體,拼音入口的結(jié)構(gòu)又包括拼音、拼音對(duì)應(yīng)的漢字以及拼音對(duì)應(yīng)的第一個(gè)漢字在漢字庫中的位置。漢字庫的正文部分包括所有拼音對(duì)應(yīng)的漢字。漢字庫的結(jié)構(gòu)如圖2所示。
圖2 漢字庫結(jié)構(gòu)示意圖
在Windows環(huán)境下可以利用豐富的資源進(jìn)行方便的編程,取得漢字信息和生成既定格式的漢字庫,但只有在ARM-Linux環(huán)境下才可以正確地確定哪些漢字無法正常顯示(即非法漢字)。所以漢字庫的創(chuàng)建流程分為在Windows環(huán)境下和在ARM-Linux環(huán)境下的處理。漢字庫的生成總體流程如圖3所示。
圖3 全拼輸入法漢字庫生成流程圖
生成全拼輸入法漢字庫一共分為5個(gè)步驟:漢字采集;生成初級(jí)漢字庫;確定QT/Embedded環(huán)境中無法正常顯示的非法漢字;剔除非法漢字和重新生成漢字庫。
全拼輸入法漢字庫生成的第一步是盡可能地取到并記錄現(xiàn)有的所有漢字的信息。在文中,將系統(tǒng)需要的輸入法設(shè)置為“中文全拼輸入法”,用程序模擬鍵盤按鍵信息輸入,可以將拼音信息和中文全拼輸入法輸出的漢字信息保存在一個(gè)文件中。直到將所有的漢語拼音信息和漢字信息記錄完成[5]。
在模擬鍵盤輸入采集漢字的過程中,有兩個(gè)指標(biāo)比較重要,即輸入次數(shù)和輸入正確率。輸入次數(shù)是指為了完成某些功能需要模擬的鍵盤輸入次數(shù)。輸入正確率是指為了完成某些功能,在輸入的過程中正確的輸入在所有輸入中所占的比例。
在模擬鍵盤輸入的過程中,假設(shè)輸入法的拼音輸入完成后選擇漢字和將漢字返回給上層窗體的操作是一定的。普通的遍歷輸入算法一般按照順序輸入英文字母作為拼音,如果組合成功則顯示并記錄漢字,否則放棄輸入自動(dòng)跳轉(zhuǎn)至下一組輸入。那么,取得所有漢字需要輸入鍵盤鍵碼的次數(shù)N和最大拼音組合的長度n之間的關(guān)系為:
N=26+262+…+26n(n>0) (n為拼音組合的最大長度)
輸入正確率 R,即輸入的正確拼音組合數(shù)Ri占所有輸入拼音組合Ra中的比例為:
其中,Ri為正確拼音組合數(shù),Ra為所有輸入拼音組合數(shù)。
如果以漢語拼音最長為6個(gè)字母長度(如:“裝”的漢語拼音為zhuang)計(jì)算,則需要鍵盤的處理321272406次。在漢語言中,正確的拼音組合數(shù)為436個(gè)。不難算出,這種方法的輸入正確率僅為0.0001357%。在主頻為2.0GHz的普通PC機(jī)上處理如此多的鍵盤輸入,經(jīng)兩次實(shí)驗(yàn)測得向緩存輸入漢字和記錄漢字到指定文件的總共時(shí)間約為190小時(shí),共采集了456個(gè)拼音,這些拼音共記錄61609個(gè)漢字。
文中在漢字采集的過程中采用一種新方法,即利用漢語拼音的特點(diǎn),將漢語拼音中的聲母和韻母進(jìn)行組合輸入。輸入拼音時(shí)將所有的聲母作為聲母源單元Sc,將所有韻母都作為韻母輸入源單元Sv,每次輸入的拼音都為一個(gè)聲母源單元和一個(gè)韻母源單元的組合,這樣可以大大減少輸入的次數(shù),提高輸入正確率。
以下就輸入次數(shù)和輸入正確率的計(jì)算進(jìn)行分析。
由于在每次輸入聲母之后都需要輸入一個(gè)韻母進(jìn)行匹配,所以韻母源單元的輸入是必不可少的,所有韻母源單元的輸入次數(shù) Nt為:
Sv-1為韻母源單元中只需輸入一次的韻母個(gè)數(shù);Sv-2為韻母源單元中需要輸入兩次的韻母個(gè)數(shù);Sv-3為韻母源單元中需要輸入三次的韻母個(gè)數(shù);Sv-4為韻母源單元中需要輸入四次的韻母個(gè)數(shù)。
組合拼音模擬輸入算法的輸入鍵盤鍵碼的次數(shù)N
Sc-1為聲母源單元中只需輸入一次的聲母個(gè)數(shù);Sc-2為聲母源單元中需要輸入兩次的聲母個(gè)數(shù)。
漢語言中聲母的個(gè)數(shù)為23個(gè),其中雙字母聲母為3個(gè),其余為單字母聲母;韻母個(gè)數(shù)為35個(gè),其中單字母韻母6個(gè),雙字母韻母13個(gè),三字母韻母12個(gè),四字母韻母4個(gè),由以上公式可以計(jì)算出需要輸入鍵盤鍵碼的次數(shù)為2268次。
由公式(1)可以計(jì)算出采用聲母韻母組合輸入拼音的輸入正確率提高到19.2239%,這比無序的輸入字母進(jìn)行漢字采集提高了1415倍。在主頻為2.0GHz的普通PC機(jī)上處理如此多的鍵盤輸入,經(jīng)多次實(shí)驗(yàn)測得向緩存輸入漢字和記錄漢字到指定文件的總共時(shí)間約為5.5小時(shí),共采集了456個(gè)拼音,這些拼音共記錄了61609個(gè)漢字。
由分析可知,在采集漢字的過程中,使用聲母和韻母組合后采集漢字的方法提高輸入的正確率,大大減少了采集漢字信息的輸入次數(shù),是一種優(yōu)秀的漢字采集方法。
漢字信息采集的時(shí)候,存儲(chǔ)拼音和漢字信息的格式如下:文件的每一行開頭的本行漢字的拼音組標(biāo)號(hào),后邊為漢字和拼音元,漢字拼音元為漢字加拼音的格式,如“啊:a0”,“啊”為漢字,“a”為拼音,“0”是“a”這個(gè)拼音在使用的輸入法中對(duì)應(yīng)的序號(hào)。具體存儲(chǔ)格式如圖4所示。
圖4 漢字采集保存的格式
取得拼音和對(duì)應(yīng)的漢字信息后,這些信息無法使中文輸入法方便地使用,因此需要將這些信息加工為指定格式的漢字和拼音對(duì)應(yīng)關(guān)系。
初級(jí)漢字庫的生成過程以上述漢字采集文件為輸入,可以在這個(gè)過程中選擇生成Unicode編碼形式或者ANSI編碼形式。選擇哪種編碼形式,由用戶根據(jù)所有的ARM-Linux系統(tǒng)及開發(fā)的輸入法的用途來決定。這里介紹的是選擇加工生成ANSI編碼形式的初級(jí)漢字庫文件。
在生成初級(jí)漢字庫之前,需要按照既定的漢字庫格式初始化漢字庫,即建立一個(gè)和既定格式相同的空文件,然后將該空漢字庫文件進(jìn)行填充。
填充空漢字庫時(shí),將采集漢字生成的漢字文件信息按行分解開來成為漢字信息單元。在每個(gè)單元的開頭有一個(gè)組號(hào),找到第一個(gè)組號(hào)為“0”的單元時(shí),將該組拼音填入到第一個(gè)拼音入口的拼音信息中,記下該漢字庫中正文的位置,將位置信息添加到拼音入口的對(duì)應(yīng)結(jié)構(gòu)。然后將該組的所有漢字部分添加到漢字庫中,并做好漢字個(gè)數(shù)的記錄,最后將漢字個(gè)數(shù)記錄寫入漢字庫拼音入口的字?jǐn)?shù)統(tǒng)計(jì)處。
將這一組的漢字和拼音信息提取并寫入漢字庫以后,再判斷下一組的漢字信息,此時(shí)如果組號(hào)不為“0”,則繼續(xù)添加本組漢字信息到漢字庫的正文部分,并將漢字字?jǐn)?shù)統(tǒng)計(jì)信息進(jìn)行更新。
依照此操作,找到下一組組號(hào)為“0”的漢字信息單元,將拼音入口的序號(hào)向后移動(dòng)一個(gè),繼續(xù)以上的操作。直到找到漢字采集文件的最后一個(gè)漢字。這樣即可將已經(jīng)按照既定格式初始化的空漢字庫填充完畢,初級(jí)漢字庫生成完成。
拼音和漢字對(duì)應(yīng)關(guān)系建立完成以后,要確定這些漢字必須可以在目標(biāo)系統(tǒng)ARM-Linux系統(tǒng)中正常顯示。內(nèi)碼就是漢字的編碼在機(jī)器內(nèi)的表示,就是通常的GBK,BIG5等,內(nèi)碼轉(zhuǎn)換就是在不同編碼的字符集間建立一種對(duì)應(yīng)關(guān)系。如果本地機(jī)器支持的編碼方式不一樣或者支持的字符集不相同,在顯示文檔時(shí)就會(huì)出現(xiàn)亂碼的情況[2]。由于Windows系統(tǒng)和ARM-Linux系統(tǒng)中的內(nèi)碼有差別,所以需要在目標(biāo)系統(tǒng)中對(duì)已經(jīng)包含的所有漢字進(jìn)行判斷,首先確定無法在目標(biāo)系統(tǒng)中顯示的漢字,即非法漢字。
初級(jí)漢字庫建立以后,在ARM-Linux系統(tǒng)中,按照輸入法可以訪問的形式,將漢字庫中的拼音和對(duì)應(yīng)漢字自動(dòng)遍歷并在ARM-Linux系統(tǒng)顯示出來,可以看出有些在Windows系統(tǒng)中的ANSI編碼形式的漢字無法在ARMLinux系統(tǒng)中正常顯示出來,這些無法正常顯示的漢字的十六進(jìn)制編碼為“EF BF BD”[4]。過程需將包括這些信息的拼音和漢字信息保存成為一個(gè)新的文檔。文檔的結(jié)構(gòu)是以拼音為單位,一個(gè)拼音后邊跟一個(gè)空格然后是這個(gè)拼音對(duì)應(yīng)的所有的漢字。至此,文檔中包括的所有的拼音信息和合法或者非法的漢字,無法正常顯示的漢字已經(jīng)被標(biāo)識(shí)完畢。
確定目標(biāo)系統(tǒng)中的非法漢字后,需要用一種方便的方法將這部分漢字剔除,這就是剔除非法漢字部分需要做的工作。剔除非法漢字,可以將所有非法漢字一次性剔除而不會(huì)影響正常漢字。
由于非法漢字的編碼已經(jīng)確定,將這個(gè)編碼的漢字剔出就較容易做到。在遍歷上一步驟生成的文件時(shí),按照順序的遍歷方法及拼音順序查找,遇到編碼為“EF BF BD”的漢字,自動(dòng)進(jìn)行剔除。
剔除非法漢字的同時(shí),為了使下一步生成真正ARM-Linux可用的漢字庫,應(yīng)將剔除非法漢字后的文件按照采集漢字后生成的文件格式進(jìn)行編輯。
剔除非法漢字后,留下的漢字都是可以在ARM-Linux下正常使用的漢字。在剔除無法正常顯示的漢字的同時(shí),將文件的格式也進(jìn)行了調(diào)整,此時(shí)可以將文件視為采集漢字時(shí)生成的文件格式,如圖4所示。
重新生成漢字庫的過程以已經(jīng)剔除非法漢字以后的文件為輸入,選擇生成Unicode編碼形式或者ANSI編碼形式。在加工過程中,還需要根據(jù)文件中的拼音組信息,更新對(duì)應(yīng)的拼音入口的信息,比如剔除一些無正確漢字對(duì)應(yīng)的拼音組。生成最終可以在目標(biāo)系統(tǒng)中正常使用的漢字庫,此時(shí)的全拼輸入法漢字庫生成完成。
文中介紹的漢字采集所采用的方法與一般的漢字采集對(duì)應(yīng)時(shí)間如表1所示。
表1 漢字采集的時(shí)間比較
除了采集漢字之外的其他步驟,都是對(duì)很小的文件進(jìn)行處理,費(fèi)時(shí)很小,除了采集漢字以外的步驟,可以在一個(gè)小時(shí)內(nèi)完成,故在整個(gè)漢字庫生成的過程中不做討論。
整個(gè)生成漢字庫的過程中,將從漢字采集文件中讀出的漢字提取出來后,將其編碼更改為指定編碼方式之后再存入漢字庫中。這樣就可以對(duì)漢字編碼形式進(jìn)行控制。
由于初級(jí)漢字庫生成后,是在ARM-Linux系統(tǒng)中進(jìn)行讀取漢字庫信息,然后由ARM-Linux系統(tǒng)對(duì)漢字庫中的漢字進(jìn)行逐字標(biāo)識(shí),所以可以保證漢字庫中的漢字都是可以在ARM-Linux系統(tǒng)正常顯示的漢字。
中文輸入法在訪問漢字庫時(shí)只需查找漢字庫的文件頭,在總數(shù)為436的拼音入口中匹配拼音,直接得到拼音對(duì)應(yīng)的首個(gè)漢字的地址,然后進(jìn)行漢字的讀取即可。完全可以滿足用戶手動(dòng)輸入拼音時(shí),對(duì)當(dāng)前拼音對(duì)應(yīng)漢字的顯示更新速度要求。整個(gè)訪問漢字庫的方法簡單易行。
全拼輸入法被初始化的時(shí)候,首先需要判斷漢字庫是否已經(jīng)存放在指定的位置,并判斷漢字庫的文件頭部分是否為已經(jīng)定義的漢字庫文件標(biāo)識(shí)符。如果文件頭匹配,則說明漢字庫已經(jīng)存在而且可用。
用戶輸入正確的拼音后,輸入法開始在漢字庫的文件頭中查找該拼音的拼音入口結(jié)構(gòu)。找到拼音入口的拼音部分和用戶輸入的拼音匹配,則返回該拼音入口的漢字存放的起始位置,然后從文件的這個(gè)位置開始讀取漢字。讀取漢字的個(gè)數(shù)則由該拼音入口的拼音對(duì)應(yīng)漢字個(gè)數(shù)來確定。此時(shí),對(duì)應(yīng)用戶輸入的拼音的漢字已經(jīng)全部讀出。將這些漢字顯示在漢字框中,用戶即可以按照自己的需要選擇正確的漢字[6、7]。
提出了一種可以適合一般的Qt/Embedded的中文全拼輸入法漢字庫生成方法,使用該方法生成的漢字庫結(jié)構(gòu)合理,對(duì)Linux系統(tǒng)中可顯示的漢字支持率可達(dá)到100%,輸入法訪問方便,而且整個(gè)生成時(shí)間只用了約6.5小時(shí)。這比傳統(tǒng)的漢字庫組織生成方法有了很大的提高,是一種優(yōu)秀的漢字庫快速生成方法。
目前,該方法已經(jīng)運(yùn)用在我國自主研發(fā)的(L-S)波段衛(wèi)星移動(dòng)通信便攜式終端(國家863項(xiàng)目)中,以此漢字庫為基礎(chǔ)的中文輸入法運(yùn)行正常。由于該方法生成漢字庫迅速,在短時(shí)間內(nèi)生成了可供(L-S)波段衛(wèi)星移動(dòng)通信便攜式終端使用的漢字庫,為其提供了中文輸入法的支持,也為我國衛(wèi)星通信爭奪(L-S)波段使用權(quán)的終端開發(fā)過程中節(jié)約了寶貴的時(shí)間。
經(jīng)過理論分析和實(shí)踐驗(yàn)證,文中的全拼輸入法漢字庫設(shè)計(jì)以及漢字庫的生成方法非常適合ARM-Linux系統(tǒng)的全拼中文輸入法使用。
[1] 李向陽,曾旖,奚大順.在UC/GUI中實(shí)現(xiàn)漢字顯示[J].單片機(jī)與嵌入式系統(tǒng)應(yīng)用,2005,(5).
[2] 童學(xué)才.基于MiniGUI的嵌入式系統(tǒng)中文輸入法設(shè)計(jì)[D].武漢:武漢科技大學(xué),2007.
[3] 喬建良,趙增建.談?wù)勈謾C(jī)的中文輸入法[J].現(xiàn)代通信,2004,(3).
[4] 廖紅玉,劉會(huì)平,陳曉云.在C#中實(shí)現(xiàn)對(duì)亂碼的正確顯示[J].微計(jì)算機(jī)應(yīng)用,2005,(4).
[5] 陳小康,江頡.支持中文編碼和中文輸入的WML編碼器的設(shè)計(jì)與實(shí)現(xiàn)[J].計(jì)算機(jī)工程與應(yīng)用,2002,(2).
[6] 錢斌.RedHat Linux中文輸入法補(bǔ)充[J].計(jì)算機(jī)應(yīng)用文摘,2001,(12).
[7] 羅帆.Linux下的中文輸入法[J].計(jì)算機(jī)應(yīng)用文摘,2003,(7).
[8] 熱依曼.吐爾遜,吾守爾.斯拉木,努爾麥麥提.多文種手機(jī)混合輸入/輸出技術(shù)及實(shí)現(xiàn)[J].計(jì)算機(jī)工程與科學(xué),2006,28(4):103-104.