自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解C#如何快速獲取助記碼

開發(fā) 后端
本文將介紹C#快速獲取助記碼,包括對(duì)于數(shù)組這樣一種線性表的解決思路。同時(shí)還會(huì)介紹一些優(yōu)缺點(diǎn),希望對(duì)大家有所幫助。

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

本文實(shí)現(xiàn):

1、以犧牲空間為代價(jià),方便快速地實(shí)現(xiàn)漢字的助記碼獲取。

2、針對(duì)拼音特性,實(shí)現(xiàn)多音字并提供顯式地姓氏調(diào)用方法。

網(wǎng)上關(guān)于使用C#取助記碼的方法很多,不過一般都是采用將每一個(gè)碼有哪些漢字的方法來實(shí)現(xiàn)助記碼的轉(zhuǎn)換,它的缺點(diǎn)是顯而易見的:

1.相當(dāng)于本來應(yīng)該存放在數(shù)據(jù)庫或者是外部的數(shù)據(jù)存放到程序中;

2.利用字符串的定位功能,性能上也不一定好。

在線性表中我們查找指定位置結(jié)點(diǎn)的數(shù)據(jù)是最快的,比如一個(gè)包含10000個(gè)元素的線性表中,無論直接訪問哪一個(gè)位置的數(shù)據(jù)值,只要根據(jù)表的***個(gè)位置就可以直接定位到第9000個(gè)元素的位置,數(shù)組也是一種簡單有效的線性表,需要某個(gè)項(xiàng)目,只要通過編移量即可搞定。

在不使用數(shù)據(jù)庫,直接使用文件做資源,方便配置,完成中文到助記碼的的轉(zhuǎn)換,同時(shí)針對(duì)拼音助記碼,還要實(shí)現(xiàn):1.多音字詞組匹配;2.姓氏專用方法。

同時(shí)五筆碼、四角碼等多種類別也易如反掌。雖然在以犧牲空間為代價(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é)構(gòu)(有更多編碼,只要在結(jié)構(gòu)上擴(kuò)充即可):

  1. private struct ItemWord{  
  2. public int numFlag; //是否多音字  
  3. public char strWord;//當(dāng)前單詞  
  4. public string strSpell1;//輸入碼  
  5. public string strSpell2;//輸入碼  
  6. public string strExt; //多音字保留串  
  7. public string strName;//用于定義姓氏碼 

 

加載助記碼字典

由于要支持拼音及多音字,也支持五筆的助記碼,為了例子方便,編碼表都暫時(shí)存放在d:\myword下,下面以拼音碼的加載為例,首先初始化Itemword中的每一個(gè)項(xiàng)目,通常情況下GBK的實(shí)際漢字?jǐn)?shù)應(yīng)該在20000字左右,從雙字節(jié)的角度來看,最多也就只有64K,因此把我們的數(shù)組定義為64K,即:

 

  1. private static readonly int INTMAX = 65536;  
  2. private ItemWord[] stWord = new ItemWord[INTMAX]; 

 

在函數(shù)fun_LoadWord中拼音碼hzpy1.txt的加載方法:

 

  1. while ((strInput = srFile.ReadLine()) != null){  
  2. chrWord = strInput.ToCharArray();  
  3. numIndex = (int)chrWord[0];  
  4. stWord[numIndex].strWord = chrWord[0];  
  5. stWord[numIndex].strSpell1 = chrWord[2].ToString(); 

 

注意,其中最最關(guān)鍵是把讀取的內(nèi)容轉(zhuǎn)成char的數(shù)組,再通過(int)chrWord[0]把它轉(zhuǎn)換為一個(gè)數(shù)組的下標(biāo)值(這個(gè)相對(duì)來說C就簡單許多),再把相應(yīng)內(nèi)容填到數(shù)組中此下標(biāo)項(xiàng)目。對(duì)于五筆碼的讀取方法也一致,非常簡單(更多的其它編碼也不在話下)。不過,拼音碼的多音存儲(chǔ),需要介紹一下,實(shí)際上對(duì)于漢字來說,單音是大多數(shù),只有少部分才是多音字,為了結(jié)構(gòu)更簡單,把多音字是存放在相應(yīng)的漢字結(jié)構(gòu)中,即:

 

  1. numIndex = (int)chrWord[0];  
  2. strInput = strInput.Substring(2);  
  3. strInput = strInput.Replace("\t"" ");  
  4. strInput = strInput.Replace(" ""/");  
  5. stWord[numIndex].strExt = stWord[numIndex].strExt + strInput + "|"

 

最終strExt中的結(jié)構(gòu)內(nèi)容是“|曾哥/Z|”的格式,它的好處會(huì)在多音碼的展現(xiàn)時(shí)進(jìn)行說明。

從漢字到簡碼

我們先舉例五筆的助記碼實(shí)現(xiàn),對(duì)傳入的漢字串來說,只要提取每一個(gè)漢字,得到對(duì)應(yīng)的字符編碼,再直接提取其對(duì)應(yīng)編碼,由于直接采用下標(biāo)取得編碼,而數(shù)據(jù)又加載在內(nèi)存數(shù)組中,可以用飛速來描述它:

 

  1. chrWord = strChinese.ToCharArray();  
  2. numCount = strChinese.Length;  
  3. for (i = 0; i < numCount; i++){  
  4. numIndex = (int)chrWord[i];  
  5. strSpell = strSpell + stWord[numIndex].strSpell2.ToString(); 

 

拼音碼,則存在著幾個(gè)主要問題,一個(gè)是姓氏,還有一個(gè)是多音字,多音字的實(shí)現(xiàn),通過詞組模式來處理,即首先它是一個(gè)多音字,即結(jié)構(gòu)中的numFlag標(biāo)志。同時(shí)根據(jù)漢字串往前往后追蹤一個(gè)形成詞組,例如“曾哥”,它雖然來源于姓氏,但是本身已經(jīng)形成一個(gè)受眾很廣的詞,在hzpy2.txt中定義“曾 曾哥 Z”這樣一行內(nèi)容。在多音字時(shí),我們用函數(shù)funFindMulti來定位多音字的編碼:

 

  1. strWord = "|" + ch1 + ch2 + "/";  
  2. numPos = stWord[numIndex].strExt.IndexOf(strWord);  
  3. if (numPos >= 0) return stWord[numIndex].strExt.Substring(numPos + strWord.Length, 1); 

 

也就是說,但我們定位漢字“曾”時(shí),首先它是一個(gè)多音字,再根據(jù)詞組“曾哥”對(duì)應(yīng)的編碼,

clip_image001[4]

我們把用于定位的詞組形成前綴“|詞組/”的格式,假定有多個(gè)多音時(shí),可以通過唯一位置定位后,再取得此串后面的字符,即“Z”,所以當(dāng)我們輸入“信曾哥得自信”時(shí),得到拼音助記碼自然就是“XZGDZX”了。因?yàn)樾帐系奶厥庑裕⑶覍?shí)際業(yè)務(wù)中,比較明確地知道,當(dāng)前的內(nèi)容是否是姓名,即我們顯式調(diào)用,而姓名中,也只有在首字時(shí)才發(fā)生按姓的讀音。只要調(diào)用參數(shù)提供是否姓名的開關(guān)(下面的變量IsName,為了文章方便,緊湊格式了)即可:

  1. if (stWord[numIndex].numFlag > 0 && !IsName){if (i > 0) strThis = funFindMulti(numIndex, chrWord[i - 1], chrWord[i]);  
  2. if (strThis.Length == 0 && i < numCount -1 ) strThis = funFindMulti(numIndex, chrWord[i], chrWord[i + 1]);  
  3. }  
  4. if (IsName && i == 0 && stWord[numIndex].strName.Length > 0)strThis = stWord[numIndex].strName;  
  5. if (strThis.Length == 0)strThis = stWord[numIndex].strSpell1.ToString();  
  6. strSpell = strSpell + strThis;  
當(dāng)所輸入的是單個(gè)的姓名時(shí),我們只處理首漢字,比如“金庸”的原名:

clip_image002[4]

對(duì)于姓名之后是否按詞組處理,比如張長春這樣的人,如果指定為姓名,可能叫“ZZC”也可能叫“ZCC”,這個(gè)很難說。所以在某種程度上,我們解決多音字,只能說是處理“多音字”中的80%問題,還是可以接受的。而且在實(shí)際業(yè)務(wù)中,像“我們這些人參他一本”這樣的字串是不會(huì)在數(shù)據(jù)字典中出現(xiàn)的。***看看多單字中有典型意義的“單”字在三種模式下的效果吧:

clip_image004[4]

這樣我們不僅可以快速處理多音字,也同時(shí)處理了多個(gè)助記碼的實(shí)現(xiàn)。在非WEB應(yīng)用的業(yè)務(wù)中,在內(nèi)存中進(jìn)行快速助記碼的過濾就會(huì)非常實(shí)用。實(shí)例中除了漢字編碼外,所提供的五筆編碼的漢字量還是不少的。

原文標(biāo)題:C#快速獲取助記碼

鏈接:http://www.cnblogs.com/hzspa/archive/2010/05/11/1732539.html

【編輯推薦】

  1. C#模式窗體中的按鈕操作
  2. C#模式窗體操作詳解
  3. C#窗體繼承原理以及實(shí)現(xiàn)淺析
  4. C#窗體關(guān)閉事件的重載實(shí)現(xiàn)淺析
  5. C#窗體位置與大小設(shè)置詳解
責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2010-09-09 11:27:22

SQL函數(shù)助記碼

2009-09-02 16:52:55

C#數(shù)組初始化

2009-08-14 17:09:48

C#引用類型

2009-07-30 18:20:21

C#繼承

2009-08-24 11:23:41

C# TimeLabe

2009-09-07 16:13:56

C# MessageB

2009-09-01 16:07:04

C#命名規(guī)約

2010-07-26 09:20:48

C#

2009-09-07 18:08:25

C#鼠標(biāo)指針

2009-08-28 10:31:47

C#字符ASCII碼

2009-08-12 17:03:22

C#變量類型轉(zhuǎn)換

2009-11-20 09:10:21

C#開發(fā)環(huán)境

2009-08-06 17:31:46

C#制作屏幕保護(hù)

2009-09-04 14:14:55

C#文檔

2009-08-27 14:29:15

C# explicti

2009-08-03 13:13:52

C#調(diào)用Outlook

2009-09-01 10:37:51

C#項(xiàng)目代碼C#代碼規(guī)范

2009-09-02 09:24:03

C# this關(guān)鍵字

2009-09-02 17:12:06

C#關(guān)機(jī)代碼

2024-03-04 18:49:59

反射C#開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)