新聞中心
希望通過(guò)本文能讓大家對(duì)C#如何快速獲取助記碼有更深刻的了解,也向您推薦《C#實(shí)用基礎(chǔ)教程》。

創(chuàng)新互聯(lián)建站為您提適合企業(yè)的網(wǎng)站設(shè)計(jì)?讓您的網(wǎng)站在搜索引擎具有高度排名,讓您的網(wǎng)站具備超強(qiáng)的網(wǎng)絡(luò)競(jìng)爭(zhēng)力!結(jié)合企業(yè)自身,進(jìn)行網(wǎng)站設(shè)計(jì)及把握,最后結(jié)合企業(yè)文化和具體宗旨等,才能創(chuàng)作出一份性化解決方案。從網(wǎng)站策劃到成都網(wǎng)站建設(shè)、成都做網(wǎng)站, 我們的網(wǎng)頁(yè)設(shè)計(jì)師為您提供的解決方案。
本文實(shí)現(xiàn):
1、以犧牲空間為代價(jià),方便快速地實(shí)現(xiàn)漢字的助記碼獲取。
2、針對(duì)拼音特性,實(shí)現(xiàn)多音字并提供顯式地姓氏調(diào)用方法。
網(wǎng)上關(guān)于使用C#取助記碼的方法很多,不過(guò)一般都是采用將每一個(gè)碼有哪些漢字的方法來(lái)實(shí)現(xiàn)助記碼的轉(zhuǎn)換,它的缺點(diǎn)是顯而易見(jiàn)的:
1.相當(dāng)于本來(lái)應(yīng)該存放在數(shù)據(jù)庫(kù)或者是外部的數(shù)據(jù)存放到程序中;
2.利用字符串的定位功能,性能上也不一定好。
在線性表中我們查找指定位置結(jié)點(diǎn)的數(shù)據(jù)是最快的,比如一個(gè)包含10000個(gè)元素的線性表中,無(wú)論直接訪問(wèn)哪一個(gè)位置的數(shù)據(jù)值,只要根據(jù)表的***個(gè)位置就可以直接定位到第9000個(gè)元素的位置,數(shù)組也是一種簡(jiǎn)單有效的線性表,需要某個(gè)項(xiàng)目,只要通過(guò)編移量即可搞定。
在不使用數(shù)據(jù)庫(kù),直接使用文件做資源,方便配置,完成中文到助記碼的的轉(zhuǎn)換,同時(shí)針對(duì)拼音助記碼,還要實(shí)現(xiàn):1.多音字詞組匹配;2.姓氏專(zhuān)用方法。
同時(shí)五筆碼、四角碼等多種類(lèi)別也易如反掌。雖然在以犧牲空間為代價(jià),但用空間換得時(shí)間的性能提高,還是非常值得的。
數(shù)據(jù)存放使用數(shù)組
數(shù)組就是一種線性表,我們的解決思路是:
1、每一個(gè)項(xiàng)目對(duì)應(yīng)一個(gè)結(jié)構(gòu),它包括漢字、拼音碼、是否多音字、五筆碼(或其它更多編碼);
2、每一個(gè)漢字直接轉(zhuǎn)換成一個(gè)數(shù)字編碼(ASCII或者是UNICODE),數(shù)字就是數(shù)組下標(biāo);
3、讀取文字串,根據(jù)每一個(gè)漢字取得數(shù)字,直接定位數(shù)組中的位置,取得編碼。
因此我們定義用于存放漢字的助記簡(jiǎn)碼的結(jié)構(gòu)(有更多編碼,只要在結(jié)構(gòu)上擴(kuò)充即可):
- private struct ItemWord{
- public int numFlag; //是否多音字
- public char strWord;//當(dāng)前單詞
- public string strSpell1;//輸入碼
- public string strSpell2;//輸入碼
- public string strExt; //多音字保留串
- public string strName;//用于定義姓氏碼
加載助記碼字典
由于要支持拼音及多音字,也支持五筆的助記碼,為了例子方便,編碼表都暫時(shí)存放在d:\myword下,下面以拼音碼的加載為例,首先初始化Itemword中的每一個(gè)項(xiàng)目,通常情況下GBK的實(shí)際漢字?jǐn)?shù)應(yīng)該在20000字左右,從雙字節(jié)的角度來(lái)看,最多也就只有64K,因此把我們的數(shù)組定義為64K,即:
- private static readonly int INTMAX = 65536;
- private ItemWord[] stWord = new ItemWord[INTMAX];
在函數(shù)fun_LoadWord中拼音碼hzpy1.txt的加載方法:
- while ((strInput = srFile.ReadLine()) != null){
- chrWord = strInput.ToCharArray();
- numIndex = (int)chrWord[0];
- stWord[numIndex].strWord = chrWord[0];
- stWord[numIndex].strSpell1 = chrWord[2].ToString();
注意,其中最最關(guān)鍵是把讀取的內(nèi)容轉(zhuǎn)成char的數(shù)組,再通過(guò)(int)chrWord[0]把它轉(zhuǎn)換為一個(gè)數(shù)組的下標(biāo)值(這個(gè)相對(duì)來(lái)說(shuō)C就簡(jiǎn)單許多),再把相應(yīng)內(nèi)容填到數(shù)組中此下標(biāo)項(xiàng)目。對(duì)于五筆碼的讀取方法也一致,非常簡(jiǎn)單(更多的其它編碼也不在話下)。不過(guò),拼音碼的多音存儲(chǔ),需要介紹一下,實(shí)際上對(duì)于漢字來(lái)說(shuō),單音是大多數(shù),只有少部分才是多音字,為了結(jié)構(gòu)更簡(jiǎn)單,把多音字是存放在相應(yīng)的漢字結(jié)構(gòu)中,即:
- numIndex = (int)chrWord[0];
- strInput = strInput.Substring(2);
- strInput = strInput.Replace("\t", " ");
- strInput = strInput.Replace(" ", "/");
- stWord[numIndex].strExt = stWord[numIndex].strExt + strInput + "|";
最終strExt中的結(jié)構(gòu)內(nèi)容是“|曾哥/Z|”的格式,它的好處會(huì)在多音碼的展現(xiàn)時(shí)進(jìn)行說(shuō)明。
從漢字到簡(jiǎn)碼
我們先舉例五筆的助記碼實(shí)現(xiàn),對(duì)傳入的漢字串來(lái)說(shuō),只要提取每一個(gè)漢字,得到對(duì)應(yīng)的字符編碼,再直接提取其對(duì)應(yīng)編碼,由于直接采用下標(biāo)取得編碼,而數(shù)據(jù)又加載在內(nèi)存數(shù)組中,可以用飛速來(lái)描述它:
- chrWord = strChinese.ToCharArray();
- numCount = strChinese.Length;
- for (i = 0; i < numCount; i++){
- numIndex = (int)chrWord[i];
- strSpell = strSpell + stWord[numIndex].strSpell2.ToString();
拼音碼,則存在著幾個(gè)主要問(wèn)題,一個(gè)是姓氏,還有一個(gè)是多音字,多音字的實(shí)現(xiàn),通過(guò)詞組模式來(lái)處理,即首先它是一個(gè)多音字,即結(jié)構(gòu)中的numFlag標(biāo)志。同時(shí)根據(jù)漢字串往前往后追蹤一個(gè)形成詞組,例如“曾哥”,它雖然來(lái)源于姓氏,但是本身已經(jīng)形成一個(gè)受眾很廣的詞,在hzpy2.txt中定義“曾 曾哥 Z”這樣一行內(nèi)容。在多音字時(shí),我們用函數(shù)funFindMulti來(lái)定位多音字的編碼:
- strWord = "|" + ch1 + ch2 + "/";
- numPos = stWord[numIndex].strExt.IndexOf(strWord);
- if (numPos >= 0) return stWord[numIndex].strExt.Substring(numPos + strWord.Length, 1);
也就是說(shuō),但我們定位漢字“曾”時(shí),首先它是一個(gè)多音字,再根據(jù)詞組“曾哥”對(duì)應(yīng)的編碼,
我們把用于定位的詞組形成前綴“|詞組/”的格式,假定有多個(gè)多音時(shí),可以通過(guò)唯一位置定位后,再取得此串后面的字符,即“Z”,所以當(dāng)我們輸入“信曾哥得自信”時(shí),得到拼音助記碼自然就是“XZGDZX”了。因?yàn)樾帐系奶厥庑?,并且?shí)際業(yè)務(wù)中,比較明確地知道,當(dāng)前的內(nèi)容是否是姓名,即我們顯式調(diào)用,而姓名中,也只有在首字時(shí)才發(fā)生按姓的讀音。只要調(diào)用參數(shù)提供是否姓名的開(kāi)關(guān)(下面的變量IsName,為了文章方便,緊湊格式了)即可:
- if (stWord[numIndex].numFlag > 0 && !IsName){if (i > 0) strThis = funFindMulti(numIndex, chrWord[i - 1], chrWord[i]);
- if (strThis.Length == 0 && i < numCount -1 ) strThis = funFindMulti(numIndex, chrWord[i], chrWord[i + 1]);
- }
- if (IsName && i == 0 && stWord[numIndex].strName.Length > 0)strThis = stWord[numIndex].strName;
- if (strThis.Length == 0)strThis = stWord[numIndex].strSpell1.ToString();
- strSpell = strSpell + strThis;
當(dāng)所輸入的是單個(gè)的姓名時(shí),我們只處理首漢字,比如“金庸”的原名:
對(duì)于姓名之后是否按詞組處理,比如張長(zhǎng)春這樣的人,如果指定為姓名,可能叫“ZZC”也可能叫“ZCC”,這個(gè)很難說(shuō)。所以在某種程度上,我們解決多音字,只能說(shuō)是處理“多音字”中的80%問(wèn)題,還是可以接受的。而且在實(shí)際業(yè)務(wù)中,像“我們這些人參他一本”這樣的字串是不會(huì)在數(shù)據(jù)字典中出現(xiàn)的。***看看多單字中有典型意義的“單”字在三種模式下的效果吧:
這樣我們不僅可以快速處理多音字,也同時(shí)處理了多個(gè)助記碼的實(shí)現(xiàn)。在非WEB應(yīng)用的業(yè)務(wù)中,在內(nèi)存中進(jìn)行快速助記碼的過(guò)濾就會(huì)非常實(shí)用。實(shí)例中除了漢字編碼外,所提供的五筆編碼的漢字量還是不少的。
當(dāng)前名稱(chēng):詳解C#如何快速獲取助記碼
網(wǎng)站鏈接:http://www.5511xx.com/article/dhhdgci.html


咨詢(xún)
建站咨詢(xún)
