由于項(xiàng)目中需要把漢字轉(zhuǎn)成拼音,并且是涉及到姓名的轉(zhuǎn)換,因此不能排除有生僻字的可能.我先是查了一下漢字編碼的知識(shí),漢字編碼知識(shí)如下:
http://www.knowsky.com/resource/gb2312tbm.htm;這里說(shuō)的是區(qū)位碼,實(shí)際上區(qū)位碼和漢字GBK碼就是同一個(gè)東西,
在區(qū)位碼的區(qū)號(hào)和位號(hào)上分別加上0xA0就得到了GB2312編碼了,但是一看編碼規(guī)律,只有第一次漢字和讀音掛鉤,第二級(jí)漢字是按照部首進(jìn)行編排的,所以應(yīng)該是沒(méi)有什么絕對(duì)的關(guān)系的。于是又在網(wǎng)上找其他的資料,用java實(shí)現(xiàn)的,網(wǎng)上流傳廣泛的有兩種方法:但是就我來(lái)看都不怎么的,第一種是把漢字讀音和相應(yīng)區(qū)的漢字對(duì)照;但是只是涉及了常用的漢字,遇到生僻字是不能轉(zhuǎn)換的;第二種號(hào)稱(chēng)完整版的方法,居然把漢字碼表的基本對(duì)應(yīng)關(guān)系放到了java類(lèi)中,并且還說(shuō)什么為了防止函數(shù)字符超過(guò)65535長(zhǎng)度的限制,用了100多個(gè)init函數(shù).我實(shí)在是不能理解.其實(shí)我想得很簡(jiǎn)單:找一個(gè)漢字拼音對(duì)照表,然后初始化時(shí)讀入到HashMap中,用漢字為Key,用拼音作為value,然后就可以獲取了.不過(guò)也考慮過(guò),GBK碼表的長(zhǎng)度有27954個(gè)漢字,從來(lái)沒(méi)有用HashMap處理過(guò)如此長(zhǎng)度得東西,不知道會(huì)不會(huì)有什么限制,不過(guò)隨便想了一下應(yīng)該不可能:第一java HashMap的長(zhǎng)度不受此限制;第而,查找漢字時(shí),在HashMap中肯定時(shí)用二分法或者更好得算法來(lái)取Value,那么最壞的情況也不過(guò)時(shí)lg2(27954),這是很快的.很快實(shí)現(xiàn)了,試了一下性能還不錯(cuò),在我的機(jī)器上:init的時(shí)間200ms,查找一個(gè)漢字的平均時(shí)間為8ms.其實(shí)之前我還想過(guò)加快速度的更好的方法:把這個(gè)漢字編碼表自己先處理一遍,先利用冒泡排序法,把編碼對(duì)應(yīng)在數(shù)據(jù)文件里排好,給每個(gè)讀音漢字對(duì)照分配固定的足夠長(zhǎng)的字符寬度,對(duì)于編碼中沒(méi)有漢字的區(qū)域,用空白代替;這樣漢字的拼音編碼關(guān)系就和漢字本身的編碼建立了聯(lián)系,減去第一個(gè)漢字的編碼值,就可以得到漢字拼音在數(shù)據(jù)文件中絕對(duì)位置了,然后就可以根據(jù)漢字本身的編碼然后用文件隨機(jī)讀取的方法,取到拼音值,不知道這樣是不是會(huì)比用hashMap的方法要快一點(diǎn)?不過(guò)既然HashMap的方案可行了.那么就暫時(shí)不取測(cè)試了.
相關(guān)的資料:
(1)
GBK漢字全拼音單字源碼表
(2)
單字多音碼表