最近打算做一个基于字符串首字符(汉字取拼音的首字母)进行查询的电话簿WEB项目,由于Web本身并不支持汉字的编码编程,因此需要求助于平台开发工具。
Google上搜到一种实现方法,是用C++实现的。以下是源码:
void GetFirstLetter(CString strName, CString& strFirstLetter)
{
TBYTE ucHigh, ucLow;
int nCode;
CString strRet;
strFirstLetter.Empty();
for (int i=0; i<strName.GetLength(); i++)
{
if ( (TBYTE)strName[i] < 0x80 )
continue;
ucHigh = (TBYTE)strName[i];
ucLow = (TBYTE)strName[i+1];
if ( ucHigh < 0xa1 || ucLow < 0xa1)
continue;
else
// Treat code by section-position as an int type parameter,
// so make following change to nCode.
nCode = (ucHigh - 0xa0) * 100 + ucLow - 0xa0;
FirstLetter(nCode, strRet);
strFirstLetter += strRet;
i++;
}
}
void FirstLetter(int nCode, CString& strLetter)
{
if(nCode >= 1601 && nCode < 1637) strLetter = _T("A");
if(nCode >= 1637 && nCode < 1833) strLetter = _T("B");
if(nCode >= 1833 && nCode < 2078) strLetter = _T("C");
if(nCode >= 2078 && nCode < 2274) strLetter = _T("D");
if(nCode >= 2274 && nCode < 2302) strLetter = _T("E");
if(nCode >= 2302 && nCode < 2433) strLetter = _T("F");
if(nCode >= 2433 && nCode < 2594) strLetter = _T("G");
if(nCode >= 2594 && nCode < 2787) strLetter = _T("H");
if(nCode >= 2787 && nCode < 3106) strLetter = _T("J");
if(nCode >= 3106 && nCode < 3212) strLetter = _T("K");
if(nCode >= 3212 && nCode < 3472) strLetter = _T("L");
if(nCode >= 3472 && nCode < 3635) strLetter = _T("M");
if(nCode >= 3635 && nCode < 3722) strLetter = _T("N");
if(nCode >= 3722 && nCode < 3730) strLetter = _T("O");
if(nCode >= 3730 && nCode < 3858) strLetter = _T("P");
if(nCode >= 3858 && nCode < 4027) strLetter = _T("Q");
if(nCode >= 4027 && nCode < 4086) strLetter = _T("R");
if(nCode >= 4086 && nCode < 4390) strLetter = _T("S");
if(nCode >= 4390 && nCode < 4558) strLetter = _T("T");
if(nCode >= 4558 && nCode < 4684) strLetter = _T("W");
if(nCode >= 4684 && nCode < 4925) strLetter = _T("X");
if(nCode >= 4925 && nCode < 5249) strLetter = _T("Y");
if(nCode >= 5249 && nCode < 5590) strLetter = _T("Z");
}
How to use:
CString strName, strRes;
strName = _T("A李小三");
GetFirstLetter(strName, strRes);
//Then the value of strRes is "LXS".
很快应用到项目中,但很快发现,上述方法竟然不能识别一些汉字的编码。究其原因,是因为上述代码主要是根据汉字的编码是由拼音排序的这个基本道理得来,而且只适用于GB2312编码。对于大字符集的GBK编码,上述方法就无能为力了。
再次搜寻和尝试了好久,有一种解决办法似乎可行。该方法把所有的汉字列在一个大数组中,然后每次都是通过在数组中循环比较的方法得出所在的拼音字母。其效率实在太低了。
难道就真的没有办法了吗?终于在论坛里找到一种完美的解决方案,是在C++Builder中实现的。其代码很简洁,实现的原理也让人难以理解。我修改了一下,在VC 6.0中调试通过。
CStringCWebEventsApp::GetFirstLetter(LPCTSTR strName)
{
static int li_SecPosValue[] = {
1601, 1637, 1833, 2078, 2274, 2302, 2433, 2594, 2787, 3106, 3212,
3472, 3635, 3722, 3730, 3858, 4027, 4086, 4390, 4558, 4684, 4925, 5249
};
static char* lc_FirstLetter[] = {
"A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "O",
"P", "Q", "R", "S", "T", "W", "X", "Y", "Z"
};
static char* ls_SecondSecTable =
"CJWGNSPGCGNE[Y[BTYYZDXYKYGT[JNNJQMBSGZSCYJSYY[PGKBZGY[YWJKGKLJYWKPJQHY[W[DZLSGMRYPYWWCCKZNKYYGTTNJJNYKKZYTCJNMCYLQLYPYQFQRPZSLWBTGKJFYXJWZLTBNCXJJJJTXDTTSQZYCDXXHGCK[PHFFSS[YBGXLPPBYLL[HLXS[ZM[JHSOJNGHDZQYKLGJHSGQZHXQGKEZZWYSCSCJXYEYXADZPMDSSMZJZQJYZC[J[WQJBYZPXGZNZCPWHKXHQKMWFBPBYDTJZZKQHY"
"LYGXFPTYJYYZPSZLFCHMQSHGMXXSXJ[[DCSBBQBEFSJYHXWGZKPYLQBGLDLCCTNMAYDDKSSNGYCSGXLYZAYBNPTSDKDYLHGYMYLCXPY[JNDQJWXQXFYYFJLEJPZRXCCQWQQSBNKYMGPLBMJRQCFLNYMYQMSQYRBCJTHZTQFRXQHXMJJCJLXQGJMSHZKBSWYEMYLTXFSYDSWLYCJQXSJNQBSCTYHBFTDCYZDJWYGHQFRXWCKQKXEBPTLPXJZSRMEBWHJLBJSLYYSMDXLCLQKXLHXJRZJMFQHXHWY"
"WSBHTRXXGLHQHFNM[YKLDYXZPYLGG[MTCFPAJJZYLJTYANJGBJPLQGDZYQYAXBKYSECJSZNSLYZHSXLZCGHPXZHZNYTDSBCJKDLZAYFMYDLEBBGQYZKXGLDNDNYSKJSHDLYXBCGHXYPKDJMMZNGMMCLGWZSZXZJFZNMLZZTHCSYDBDLLSCDDNLKJYKJSYCJLKWHQASDKNHCSGANHDAASHTCPLCPQYBSDMPJLPZJOQLCDHJJYSPRCHN[NNLHLYYQYHWZPTCZGWWMZFFJQQQQYXACLBHKDJXDGMMY"
"DJXZLLSYGXGKJRYWZWYCLZMSSJZLDBYD[FCXYHLXCHYZJQ[[QAGMNYXPFRKSSBJLYXYSYGLNSCMHZWWMNZJJLXXHCHSY[[TTXRYCYXBYHCSMXJSZNPWGPXXTAYBGAJCXLY[DCCWZOCWKCCSBNHCPDYZNFCYYTYCKXKYBSQKKYTQQXFCWCHCYKELZQBSQYJQCCLMTHSYWHMKTLKJLYCXWHEQQHTQH[PQ[QSCFYMNDMGBWHWLGSLLYSDLMLXPTHMJHWLJZYHZJXHTXJLHXRSWLWZJCBXMHZQXSDZP"
"MGFCSGLSXYMJSHXPJXWMYQKSMYPLRTHBXFTPMHYXLCHLHLZYLXGSSSSTCLSLDCLRPBHZHXYYFHB[GDMYCNQQWLQHJJ[YWJZYEJJDHPBLQXTQKWHLCHQXAGTLXLJXMSL[HTZKZJECXJCJNMFBY[SFYWYBJZGNYSDZSQYRSLJPCLPWXSDWEJBJCBCNAYTWGMPAPCLYQPCLZXSBNMSGGFNZJJBZSFZYNDXHPLQKZCZWALSBCCJX[YZGWKYPSGXFZFCDKHJGXDLQFSGDSLQWZKXTMHSBGZMJZRGLYJB"
"PMLMSXLZJQQHZYJCZYDJWBMYKLDDPMJEGXYHYLXHLQYQHKYCWCJMYYXNATJHYCCXZPCQLBZWWYTWBQCMLPMYRJCCCXFPZNZZLJPLXXYZTZLGDLDCKLYRZZGQTGJHHGJLJAXFGFJZSLCFDQZLCLGJDJCSNZLLJPJQDCCLCJXMYZFTSXGCGSBRZXJQQCTZHGYQTJQQLZXJYLYLBCYAMCSTYLPDJBYREGKLZYZHLYSZQLZNWCZCLLWJQJJJKDGJZOLBBZPPGLGHTGZXYGHZMYCNQSYCYHBHGXKAMTX"
"YXNBSKYZZGJZLQJDFCJXDYGJQJJPMGWGJJJPKQSBGBMMCJSSCLPQPDXCDYYKY[CJDDYYGYWRHJRTGZNYQLDKLJSZZGZQZJGDYKSHPZMTLCPWNJAFYZDJCNMWESCYGLBTZCGMSSLLYXQSXSBSJSBBSGGHFJLYPMZJNLYYWDQSHZXTYYWHMZYHYWDBXBTLMSYYYFSXJC[DXXLHJHF[SXZQHFZMZCZTQCXZXRTTDJHNNYZQQMNQDMMG[YDXMJGDHCDYZBFFALLZTDLTFXMXQZDNGWQDBDCZJDXBZGS"
"QQDDJCMBKZFFXMKDMDSYYSZCMLJDSYNSBRSKMKMPCKLGDBQTFZSWTFGGLYPLLJZHGJ[GYPZLTCSMCNBTJBQFKTHBYZGKPBBYMTDSSXTBNPDKLEYCJNYDDYKZDDHQHSDZSCTARLLTKZLGECLLKJLQJAQNBDKKGHPJTZQKSECSHALQFMMGJNLYJBBTMLYZXDCJPLDLPCQDHZYCBZSCZBZMSLJFLKRZJSNFRGJHXPDHYJYBZGDLQCSEZGXLBLGYXTWMABCHECMWYJYZLLJJYHLG[DJLSLYGKDZPZXJ"
"YYZLWCXSZFGWYYDLYHCLJSCMBJHBLYZLYCBLYDPDQYSXQZBYTDKYXJY[CNRJMPDJGKLCLJBCTBJDDBBLBLCZQRPPXJCJLZCSHLTOLJNMDDDLNGKAQHQHJGYKHEZNMSHRP[QQJCHGMFPRXHJGDYCHGHLYRZQLCYQJNZSQTKQJYMSZSWLCFQQQXYFGGYPTQWLMCRNFKKFSYYLQBMQAMMMYXCTPSHCPTXXZZSMPHPSHMCLMLDQFYQXSZYYDYJZZHQPDSZGLSTJBCKBXYQZJSGPSXQZQZRQTBDKYXZK"
"HHGFLBCSMDLDGDZDBLZYYCXNNCSYBZBFGLZZXSWMSCCMQNJQSBDQSJTXXMBLTXZCLZSHZCXRQJGJYLXZFJPHYMZQQYDFQJJLZZNZJCDGZYGCTXMZYSCTLKPHTXHTLBJXJLXSCDQXCBBTJFQZFSLTJBTKQBXXJJLJCHCZDBZJDCZJDCPRNPQCJPFCZLCLZXZDMXMPHJSGZGSZZQLYLWTJPFSYASMCJBTZKYCWMYTCSJJLJCQLWZMALBXYFBPNLSFHTGJWEJJXXGLLJSTGSHJQLZFKCGNNNSZFDEQ"
"FHBSAQTGYLBXMMYGSZLDYDQMJJRGBJTKGDHGKBLQKBDMBYLXWCXYTTYBKMRTJZXQJBHLMHMJJZMQASLDCYXYQDLQCAFYWYXQHZ";
CString result;
int H, L, W;
UINT i, stringlen = _tcslen(strName);
int j;
for (i = 0; i < stringlen; i++) {
H = (UCHAR) (strName[i + 0]);
L = (UCHAR) (strName[i + 1]);
if (H < 0xA1 || L < 0xA1) {
result += strName[i];
continue;
} else {
W = (H - 160) * 100 + L - 160;
}
if (W > 1600 && W < 5590) {
for (j = 22; j >= 0; j--) {
if (W >= li_SecPosValue[j]) {
result += lc_FirstLetter[j];
i ++;
break;
}
}
continue;
} else {
i++;
W = (H - 160 - 56) * 94 + L - 161;
if (W >= 0 && W <= 3007)
result += ls_SecondSecTable[W];
else {
result += (char) H;
result += (char) L;
}
}
}
return result;
}
上述代码的特殊之处在于,它使用了一个二级拼音哈希表。该哈希表可能综合了大字符集中汉字的排布规律。具体原理还待进一步研究。
相关推荐
汉字转拼音首字母(UTF-8支持多音字,GB2312不支持多音字),程序hz2py_GB2312_Non-polyphone.cpp在Windows系统下VC 6.0运行通过,程序hz2py_UTF-8_Polyphone.c在Ubuntu的Linux系统下运行通过,前者不支持多音字,后者...
VC 拼音首字母大写自动转换程序,获取汉字的拼音首字母,并把首字母转换成大写,这是个VC.NET程序,我电脑上暂时没有编译环境,没有抓到截图,部分代码如下: class CUpperFirstLetterApp : public CWinAppEx { ...
VC 简单实现汉字转换拼音小程序,把输入框内用户输入的中文汉字全部转换成拼音来显示,如演示截图所示。程序原理是使用IFELanguage接口分隔中文语句并对单词加注拼音的演示,作者为ccrun。
提取汉字的是首字母,方便通过首字母检索汉字
C++源代码(VC6.0),实现汉字转拼音功能。
在我们用手机的时候,查找电话本只要输入名字的首字母就可查找到,这个程序,正是由汉字得到字母的例子!
编程语言:VC++ MFC 实现功能:根据姓名或姓名的首字母拼音查询人员信息;实现了开机自动启动;最小化系统托盘图标等功能;VC对XML文件的操作。 对初学者有很大帮助。
采用VS2013编写,可以通过拼音(可加声调)得到汉字,通过汉字得到拼音和声调...根据拼音在2500常用汉字中查找一个汉字 //2.根据拼音在所有汉字中查找一个汉字 //3.根据汉字得到一个拼音(包含声调) 工程源码打包,有调用代码
vc实现获取文件图标,简单方便,易学易懂。
用VC++语言得到输入汉字拼音码的演示小程序。
使用vc6.0写的一个类,支持汉字转化为拼音,根据拼音查找汉字,提取汉字字符串的首字母,查表方式,可以根据需要进行扩展字库。
VC实现获取系统进程,通过使用CreateToolhelp32Snapshot函数给当前系统内执行的进程拍快照,获得一个进程列表
VC编程实现获取主机名和IP地址,适合初学者
VC6.0实现获取硬盘序列号及CPUID的DLL源程序,压缩包里有代码,也有已经生成的DLL,个人XP及WIN7_32下有用过
本文实例讲述了VC实现获取当前正在运行的进程。分享给大家供大家参考。具体实现方法如下: #include #include #include int main(int argc,char* argv[]) { PROCESSENTRY32 pe32; //再使用这个结构体前先定义它...
VC中获取窗口句柄的各种方法
vc获取命令行参数并显示,用于打开系统菜单,调用各种函数,调用方法: 在命令行模式运行 >lx test.txt 1 Hello World! 3 open=test.txt open2=1
VC6.0实现获取硬盘序列号及CPUID的DLL源程序.7z
在VC中实现OpenGL三维绘图,opengl实现三维绘图 在VC中实现三维交汇图系统演示,主窗口是可以旋转的三维立体坐标系,还可以观察到在x,y,z方向上的投影。
VC6 获取CPUID VC6 获取CPUID VC6 获取CPUID VC6 获取CPUID VC6 获取CPUID