六一儿童节的礼物:基于GB18030-2000汉字拼音类库(C++)
2011-05-30 22:02
441 查看
开发工具:
Visual Studio v2010
Windows SDK v7.1
版本历史:
V1.0 2011年5月30日
实现GB18030-2000汉字拼音模块。
功能描述:
通过汉字获取拼音(基于频率排序)。可查询的汉字编码范围为0x3400~0x9FA5 0xF900~0xFAD9。
获取指定字符集的同音字列表(基于频率排序)。
数字标调音节和字符标调音节之间的互相转换。
音节排序(基于新华字典序)。
将兼容码字符转换为标准字符。
下载地址:
HYPY_Mandarin_CPlusPlus.zip
源代码:
HYPY_Mandarin.h
HYPY_Mandarin.cpp
Visual Studio v2010
Windows SDK v7.1
版本历史:
V1.0 2011年5月30日
实现GB18030-2000汉字拼音模块。
功能描述:
通过汉字获取拼音(基于频率排序)。可查询的汉字编码范围为0x3400~0x9FA5 0xF900~0xFAD9。
获取指定字符集的同音字列表(基于频率排序)。
数字标调音节和字符标调音节之间的互相转换。
音节排序(基于新华字典序)。
将兼容码字符转换为标准字符。
下载地址:
HYPY_Mandarin_CPlusPlus.zip
源代码:
HYPY_Mandarin.h
/* ---------------------------------------------------------- 文件名称:HYPY_Mandarin.h 作者:秦建辉 MSN:splashcn@msn.com 版本历史: V1.0 2011年5月30日 实现GB18030-2000汉字拼音模块。 功能描述: 1.通过汉字获取拼音(基于频率排序)。可查询的汉字编码范围为0x3400~0x9FA5 0xF900~0xFAD9。 2.获取指定字符集的同音字列表(基于频率排序)。 3.数字标调音节和字符标调音节之间的互相转换。 4.音节排序(基于新华字典序)。 5.将兼容码字符转换为标准字符。 ------------------------------------------------------------ */ #pragma once #include <Windows.h> class Pinyin { public: // 常量 static const INT SYLLABLE_NUM = 1402; // 音节总类数 static const DWORD NormZoneBegin = 0x3400; // 标准码区间起始编码 static const DWORD NormZoneEnd = 0x9FA5; // 标准码区间结束编码 static const DWORD CompatibilityZoneBegin = 0xF900; // 兼容码区间起始编码 static const DWORD CompatibilityZoneEnd = 0xFAFF; // 兼容码区间结束编码 // 枚举类型 enum TCharSet {GB2312 = 0x01, GBK = 0x02, GB18030 = 0x04}; // 字符集 public: /* 功能:获取汉字拼音音节索引集 参数说明: dwUCS4:汉字UCS4编码 hSyllableSet:句柄,其内容指向拼音音节索引区。 返回值: -1:参数错误 0:读音未知 >0:读音数 */ static INT Pronunciation( DWORD dwUCS4, const WORD** hSyllableSet ); /* 功能:获取索引对应的拼音音节 参数说明: pSyllable:存储拼音音节(要求不少于16个单元),为NULL结束的Unicode字符串。 iIndex:音节索引号 isDigitTone: true:音节使用数字标调 false:音节使用字符标调 isUppercase: true:音节使用大写字母形式 false:音节使用小写字母形式 返回值: -1:参数错误 >0:音节长度 调用说明: pSyllable的存储空间不少于16个单元 */ static INT Syllable( WCHAR* pSyllable, INT iIndex, BOOL isDigitTone = TRUE, BOOL isUppercase = TRUE ); /* 功能:获取音节索引对应的同音字集 参数说明: pHomophone:存储同音字结果。可以为NULL。 iIndex:音节索引号 cs: GB2312:GB2312字符集内的同音字 GBK:GBK字符集内的同音字 GB18030:GB18030-2000字符集内的同音字 返回值: -1:参数错误 >=0:同音字个数 调用说明: 第一次调用设置pHomophone为NULL,获得同音字个数 按(同音字个数+1)为pHomophone申请空间 第二次调用传入已分配空间的pHomophone获得同音字集 */ static INT Homophone( WCHAR* pHomophone, INT iIndex, TCharSet cs = GB2312 ); /* 功能:将字符标调音节转成数字标调音节 参数说明: pDigitToneSyllable:存储转换后的数字标调音节,其存储空间不少于16个单元 pCharToneSyllable:要转换的字符标调音节 isUppercase: true:输出大写字母形式的数字标调音节 false:输出小写字母形式的数字标调音节 返回值: -1:参数错误 >0:数字标调音节长度 调用说明: pDigitToneSyllable的存储空间不少于16个单元 */ static INT CharTone2DigitTone( WCHAR* pDigitToneSyllable, const WCHAR* pCharToneSyllable, BOOL isUppercase = TRUE ); /* 功能:将数字标调音节转成字符标调音节 参数说明: pCharToneSyllable:存储转换后的字符标调音节,其存储空间不少于16个单元 pDigitToneSyllable:要转换的数字标调音节 isUppercase: true:输出大写字母形式的字符标调音节 false:输出小写字母形式的字符标调音节 返回值: -1:参数错误 -2:音节错误 >0:字符标调音节长度 调用说明: pCharToneSyllable的存储空间不少于16个单元 */ static INT DigitTone2CharTone( WCHAR* pCharToneSyllable, const WCHAR* pDigitToneSyllable, BOOL isUppercase = FALSE ); /* 功能:基于数字标调的汉语拼音串比较函数(新华字典序) 参数说明: x:数字标调的音节x y:数字标调的音节y 返回值: -1:x排在y前面 0:x与y位置相同 1:x排在y后面 */ static INT PinyinCompare( const WCHAR* x, const WCHAR* y ); public: /* 功能:将UTF8编码转换成UCS4编码 参数: pbUTF8:要转换的UTF8编码 dwUCS4:存储转换后的UCS4编码 返回值: 0:参数错误或无效的UTF8编码 1-6:UTF8编码的有效长度 */ static INT UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 ); /* 功能:将UCS4编码转换成UTF16编码 参数: dwUCS4:要转换的UCS4编码 pwUTF16:用于存储转换后的UTF16编码。设为NULL,可以获取长度信息(字符数) 返回值: 0:无效的UCS4编码 1:转换成1个UTF16编码 2:转换成2个UTF16编码(代理项对) */ static INT UCS4_To_UTF16( DWORD dwUCS4, WCHAR* pwUTF16 ); /* 功能:将UTF16编码转换成UCS4编码 参数: pwUTF16:需要转换的UTF16编码 dwUCS4:存储转换后的UCS4编码 返回值: 0:参数错误或无效的UTF16编码 1:1个UTF16编码被转换 2:2个UTF16编码被转换(代理项对) */ static INT UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 ); /* 功能:将字符转成大写字母 参数说明: wCode:要转换的字符 返回值: 对应的大写字母 说明: 由于没有语言信息,对土耳其语的i处理有问题 */ static WCHAR CharToUpper( WCHAR wCode ); /* 功能:将字符转成小写字母 参数说明: wCode:要转换的字符 返回值: 对应的小写字母 说明: 由于没有语言信息,对土耳其语的I处理有问题 */ static WCHAR CharToLower( WCHAR wCode ); /* 功能:将字符串转换成大写串 参数说明: strDestination:目标字符串 strSource:源字符串 返回值: 目标字符串 */ static WCHAR* StringToUpper( WCHAR* strDestination, const WCHAR* strSource ); /* 功能:将字符串转换成小写串 参数说明: strDestination:目标字符串 strSource:源字符串 返回值: 目标字符串 */ static WCHAR* StringToLower( WCHAR* strDestination, const WCHAR* strSource ); /* 功能:获取字符所属的字符集组合(GB2312、GBK、GB18030) 参数说明: dwUCS4:汉字UCS4编码 返回值: 汉字所属的字符集组合 0x01:GB2312 0x02:GBK 0x04:GB18030 调用说明: 只能判断0x3400~0x9FA5之间的字符 */ static BYTE CharSetClass( DWORD dwUCS4 ); /* 功能:将兼容码字符转换为标准码字符 参数说明: dwUCS4:汉字UCS4编码 返回值: 如果是兼容码字符,则返回转换后的标准码字符,否则不变 调用说明: 只处理0xF900~0xFAFF之间的兼容码字符 */ static DWORD Compatibility2Norm( DWORD dwUCS4 ); protected: /* 功能:单音节比较函数 参数说明: x:数字标调的音节x iLenX:x音节有效长度,如果为-1,则x为NULL结束的字符串,长度为整个字符串长度 y:数字标调的音节y iLenY:y音节有效长度,如果为-1,则y为NULL结束的字符串,长度为整个字符串长度 返回值: -1:x排在y前面 0:x与y位置相同 1:x排在y后面 */ static INT MonoSyllableCompare(const WCHAR* x, INT iLenX, const WCHAR* y, INT iLenY); };
HYPY_Mandarin.cpp
#include "HYPY_Mandarin.h" #include <wchar.h> // 音节相关 extern "C" const WORD awCharToSyllableTable[]; extern "C" const WORD awSyllableEndIndex[]; extern "C" const BYTE abSyllableMap[]; // 同音字相关 extern "C" const WORD awHomophoneEndIndex[]; extern "C" const WORD awHomophoneMap[]; extern "C" const BYTE abHZClass[]; // 声调转换 extern "C" const WORD awCharTone2DigitToneTable[][3]; #define CHARTONE_DIGITTONE_NUM 64 // 字符标调组合数 // 兼容码相关 extern "C" const WORD awCompatibility2Norm[][2]; #define COMPATIBILITY_VARIANT_NUM 451 // 兼容码字符个数 // 大小写相关 extern "C" const WORD awSpecialTwins[][2]; #define SPECIAL_TWINS_NUM 9 // 特殊大小写字符个数 extern "C" const WORD awCapitalLetterZone[][3]; #define CAPITAL_LETTER_ZONE_NUM 19 // 大写字符区域 // 转换UTF8编码到UCS4编码 INT Pinyin::UTF8_To_UCS4( const BYTE* pbUTF8, DWORD& dwUCS4 ) { INT i, iLen; BYTE b; if( pbUTF8 == NULL ) { // 参数错误 return 0; } b = *pbUTF8++; if( b < 0x80 ) { dwUCS4 = b; return 1; } if( b < 0xC0 || b > 0xFD ) { // 非法UTF8 return 0; } // 确定编码长度 if( b < 0xE0 ) { dwUCS4 = b & 0x1F; iLen = 2; } else if( b < 0xF0 ) { dwUCS4 = b & 0x0F; iLen = 3; } else if( b < 0xF8 ) { dwUCS4 = b & 7; iLen = 4; } else if( b < 0xFC ) { dwUCS4 = b & 3; iLen = 5; } else { dwUCS4 = b & 1; iLen = 6; } for( i = 1; i < iLen; i++ ) { b = *pbUTF8++; if( b < 0x80 || b > 0xBF ) { // 非法UTF8 break; } dwUCS4 = (dwUCS4 << 6) + (b & 0x3F); } if( i < iLen ) { // 非法UTF8 return 0; } else { return iLen; } } // 转换UCS4编码或者UCS2编码到UTF16编码 INT Pinyin::UCS4_To_UTF16( DWORD dwUCS4, WCHAR* pwUTF16 ) { if( dwUCS4 <= 0xFFFF ) { if( pwUTF16 != NULL ) { *pwUTF16 = static_cast<WORD>(dwUCS4); } return 1; } else if( dwUCS4 <= 0xEFFFF ) { if( pwUTF16 != NULL ) { // 代理项对 pwUTF16[0] = static_cast<WORD>(0xD800 + (dwUCS4 >> 10) - 0x40); // 高10位 pwUTF16[1] = static_cast<WORD>(0xDC00 + (dwUCS4 & 0x03FF)); // 低10位 } return 2; } else { return 0; } } // 转换UCS2编码到UCS4编码 INT Pinyin::UTF16_To_UCS4( const WORD* pwUTF16, DWORD& dwUCS4 ) { WORD w1, w2; if( pwUTF16 == NULL ) { // 参数错误 return 0; } w1 = pwUTF16[0]; if( w1 >= 0xD800 && w1 <= 0xDFFF ) { // 编码在代理项区域(Surrogate Area) if( w1 < 0xDC00 ) { w2 = pwUTF16[1]; if( w2 >= 0xDC00 && w2 <= 0xDFFF ) { dwUCS4 = (w2 & 0x03FF) + (((w1 & 0x03FF) + 0x40) << 10); return 2; } } return 0; // 非法UTF16编码 } else { dwUCS4 = w1; return 1; } } // 将字符转换成大写字母 WCHAR Pinyin::CharToUpper( WCHAR wUCS2 ) { // 特殊希腊字符 if( wUCS2 == 0x03C2 ) return 0x03A3; // 特例处理 for( INT i = 0; i < SPECIAL_TWINS_NUM; i++ ) { if( wUCS2 == awSpecialTwins[i][1] ) { return awSpecialTwins[i][0]; } } // 区域处理 for( INT i = 0; i < CAPITAL_LETTER_ZONE_NUM; i++ ) { WORD wBegin = awCapitalLetterZone[i][0]; WORD wEnd = awCapitalLetterZone[i][1]; WORD wType = awCapitalLetterZone[i][2]; if( wUCS2 < wBegin )break; if( wType == 1 || wType == 2 ) { wBegin++; wEnd++; } else { wBegin += wType; wEnd += wType; } if( wUCS2 >= wBegin && wUCS2 <= wEnd ) { if( wType == 1 ) { // 大写字母编码为偶数,大小写连在一起 if( wUCS2 % 2 != 0 ) wUCS2--; } else if( wType == 2 ) { // 大写字母编码为奇数,大小写连在一起 if( wUCS2 % 2 == 0 ) wUCS2--; } else { // 大小写字母没有连在一起,而是在各自的区域块 wUCS2 -= wType; } break; } } // End for i return wUCS2; } // 将字符转换成小写字母 WCHAR Pinyin::CharToLower( WCHAR wUCS2 ) { // 特例处理 for( INT i = 0; i < SPECIAL_TWINS_NUM; i++ ) { if( wUCS2 == awSpecialTwins[i][0] ) { return awSpecialTwins[i][1]; } } for( INT i = 0; i < CAPITAL_LETTER_ZONE_NUM; i++ ) { WORD wBegin = awCapitalLetterZone[i][0]; WORD wEnd = awCapitalLetterZone[i][1]; WORD wType = awCapitalLetterZone[i][2]; if( wUCS2 < wBegin )break; if( wUCS2 >= wBegin && wUCS2 <= wEnd ) { if( wType == 1 ) { // 大写字母编码为偶数,大小写连在一起 if( wUCS2 % 2 == 0 ) wUCS2++; } else if( wType == 2 ) { // 大写字母编码为奇数,大小写连在一起 if( wUCS2 % 2 != 0 ) wUCS2++; } else { // 大小写字母没有连在一起,而是在各自的区域块 wUCS2 += wType; } break; } } // End for i return wUCS2; } // 转换成大写字母形式 WCHAR* Pinyin::StringToUpper( WCHAR* strDestination, const WCHAR* strSource ) { if(strDestination == NULL || strSource == NULL)return NULL; WCHAR* p = strDestination; while(*strDestination++ = CharToUpper(*strSource++)); return p; } // 转换成小写字母形式 WCHAR* Pinyin::StringToLower( WCHAR* strDestination, const WCHAR* strSource ) { if(strDestination == NULL || strSource == NULL)return NULL; WCHAR* p = strDestination; while(*strDestination++ = CharToLower(*strSource++)); return p; } // 获取字符所属的字符集组合(GB2312、GBK、GB18030) BYTE Pinyin::CharSetClass( DWORD dwUCS4 ) { BYTE ucClass = 0; if (dwUCS4 >= NormZoneBegin && dwUCS4 <= NormZoneEnd) { INT iSpan = dwUCS4 - NormZoneBegin; ucClass = abHZClass[iSpan >> 1]; if (iSpan % 2 == 0) { // 字节低4Bit ucClass &= 0x0F; } else { // 字节高4Bit ucClass >>= 4; } } return ucClass; } // 将兼容码字符转换为标准码字符 DWORD Pinyin::Compatibility2Norm( DWORD dwUCS4 ) { // 兼容码区间 if (dwUCS4 >= CompatibilityZoneBegin && dwUCS4 <= CompatibilityZoneEnd) { // 折半查找 INT iBegin = 0; INT iEnd = COMPATIBILITY_VARIANT_NUM - 1; while (iBegin <= iEnd) { INT iMiddle = (iBegin + iEnd) >> 1; DWORD dwCode = awCompatibility2Norm[iMiddle][0]; if (dwUCS4 > dwCode) { iBegin = iMiddle + 1; } else if (dwUCS4 < dwCode) { iEnd = iMiddle - 1; } else { // 返回标准码 return awCompatibility2Norm[iMiddle][1]; } } } // 返回原始码 return dwUCS4; } // 获取汉字的拼音音节索引集 INT Pinyin::Pronunciation( DWORD dwUCS4, const WORD** hSyllableSet ) { // 入口参数判断 if( hSyllableSet == NULL ) { return -1; // 参数错误 } *hSyllableSet = NULL; // 将兼容码字符转换到标准码字符 dwUCS4 = Compatibility2Norm(dwUCS4); // 有效区间0x3400~0x9FA5,共计27484个有效汉字 if (dwUCS4 >= NormZoneBegin && dwUCS4 <= NormZoneEnd) { INT iIndex = dwUCS4 - NormZoneBegin; WORD wKey = awCharToSyllableTable[iIndex]; if (wKey != 0xFFFF) { if (wKey < (NormZoneEnd - NormZoneBegin + 1)) { // 单音字 *hSyllableSet = awCharToSyllableTable + iIndex; return 1; } else { // 多音字,二次定位 *hSyllableSet = awCharToSyllableTable + wKey + 1; return awCharToSyllableTable[wKey]; } } } // 读音未知 return 0; } // 获取索引对应的拼音音节 INT Pinyin::Syllable( WCHAR* pSyllable, INT iIndex, BOOL isDigitTone, BOOL isUppercase ) { if( pSyllable == NULL || iIndex < 0 || iIndex >= SYLLABLE_NUM ) { return -1; // 参数错误 } WORD wBegin, wEnd; DWORD dwUCS4; // 音节起始位置 if( iIndex == 0 ) wBegin = 0; else wBegin = awSyllableEndIndex[iIndex - 1]; // 音节结束位置 wEnd = awSyllableEndIndex[iIndex]; // 将音节由UTF-8转换为UTF-16 INT iNum = 0; if(isDigitTone) { // 数字标调 WORD wTone = '5'; // 声调初始化 while( wBegin < wEnd ) { wBegin += UTF8_To_UCS4( abSyllableMap + wBegin, dwUCS4 ); if( dwUCS4 == 0x0300 ) wTone = '4'; else if( dwUCS4 == 0x0301 ) wTone = '2'; else if( dwUCS4 == 0x0304 ) wTone = '1'; else if( dwUCS4 == 0x030C ) wTone = '3'; else { if( dwUCS4 == '-' ) { // 多音节 pSyllable[iNum++] = wTone; pSyllable[iNum++] = '-'; wTone = '5'; // 声调初始化 } else { iNum += UCS4_To_UTF16( dwUCS4, pSyllable + iNum ); } } } // End While pSyllable[iNum++] = wTone; } else { // 字符标调 while( wBegin < wEnd ) { wBegin += UTF8_To_UCS4( abSyllableMap + wBegin, dwUCS4 ); iNum += UCS4_To_UTF16( dwUCS4, pSyllable + iNum ); } // End While } pSyllable[iNum] = 0; // 写入字符串结束标记 if(isUppercase) { // 转换到大写字母 StringToUpper( pSyllable, pSyllable ); } return iNum; } // 获取音节的同音字集 INT Pinyin::Homophone( WCHAR* pHomophone, INT iIndex, TCharSet cs ) { if( iIndex < 0 || iIndex >= SYLLABLE_NUM ) { return -1; // 参数错误 } // 开始索引位置 INT iBegin; if( iIndex == 0 ) iBegin = 0; else iBegin = awHomophoneEndIndex[iIndex - 1]; // 结束索引位置 INT iEnd = awHomophoneEndIndex[iIndex]; INT iNum = 0; while(iBegin < iEnd) { DWORD dwUCS4; iBegin += UTF16_To_UCS4( awHomophoneMap + iBegin, dwUCS4 ); if((CharSetClass(dwUCS4) & cs) != 0) // 字符集检测 { // 在所要求的字符集内 if(pHomophone == NULL) { if(dwUCS4 <= 0xFFFF) iNum++; else iNum += 2; } else { iNum += UCS4_To_UTF16(dwUCS4, pHomophone + iNum); } } } if(pHomophone != NULL) { pHomophone[iNum] = 0; // 写入字符串结束标记 } return iNum; } // 将字符标调音节转成数字标调音节 INT Pinyin::CharTone2DigitTone( WCHAR* pDigitToneSyllable, const WCHAR* pCharToneSyllable, BOOL isUppercase ) { if((pCharToneSyllable == NULL) || (pDigitToneSyllable == NULL)) { return -1; } WCHAR wUCS2, wTone; INT iNum = 0; wTone = '5'; // 声调初始化 while( (wUCS2 = *pCharToneSyllable++) != 0 ) { if(wUCS2 == '-') { pDigitToneSyllable[iNum++] = wTone; pDigitToneSyllable[iNum++] = '-'; wTone = '5'; } else { INT i; for(i = 0; i < CHARTONE_DIGITTONE_NUM; i++) { if(wUCS2 == awCharTone2DigitToneTable[i][0]) { // 音调字符 wTone = awCharTone2DigitToneTable[i][2]; if(awCharTone2DigitToneTable[i][1] != 0) { pDigitToneSyllable[iNum++] = awCharTone2DigitToneTable[i][1]; } break; } } if(i == CHARTONE_DIGITTONE_NUM) { // 非音调字符 pDigitToneSyllable[iNum++] = wUCS2; } } } // End While pDigitToneSyllable[iNum++] = wTone; pDigitToneSyllable[iNum] = 0; // 写入字符串结束标记 if(isUppercase) { // 转换到大写字母 StringToUpper( pDigitToneSyllable, pDigitToneSyllable ); } else { // 转换到小写字母 StringToLower( pDigitToneSyllable, pDigitToneSyllable ); } return iNum; } // 将数字标调音节转成字符标调音节 INT Pinyin::DigitTone2CharTone( WCHAR* pCharToneSyllable, const WCHAR* pDigitToneSyllable, BOOL isUppercase ) { // 可标调字符集 const WCHAR ToneCharSet[] = {'a', 'o', 'e', 'i', 'u', 0x00FC, 0x00EA, 'n', 'm'}; const WCHAR CombiningCharSet[] = {0x0304, 0x0301, 0x030C, 0x0300}; const INT ToneCharNum = sizeof(ToneCharSet) / sizeof(WCHAR); if((pDigitToneSyllable == NULL) || (pCharToneSyllable == NULL)) { return -1; // 参数错误 } INT iNum = 0; while( *pDigitToneSyllable != 0 ) { INT iLen; // 定位连接符 const WCHAR* pHyphen = wcschr( pDigitToneSyllable, '-' ); if(pHyphen == NULL) { // 单音节 iLen = wcslen( pDigitToneSyllable ) - 1; } else { // 多音节 iLen = pHyphen - pDigitToneSyllable - 1; } if(iLen < 1)return -2; // 音节错误 // 获取数字声调 WCHAR wTone = pDigitToneSyllable[iLen]; if(wTone >= '1' && wTone <= '4') { // 获取插入点 INT i; for(i = 0; i < ToneCharNum; i++) { // 查找可标调字符 WCHAR wUCS2 = ToneCharSet[i]; const WCHAR* pInsert = wmemchr( pDigitToneSyllable, wUCS2, iLen ); if( pInsert == NULL ) { pInsert = wmemchr( pDigitToneSyllable, CharToUpper(wUCS2), iLen ); } if( pInsert != NULL ) { // 找到插入点 pInsert++; if(CharToLower(wUCS2) == 'i') // 处理特例"iu" { if((pInsert < pDigitToneSyllable + iLen) && CharToLower(*pInsert) == 'u') { pInsert++; } } INT iCount = pInsert - pDigitToneSyllable; wcsncpy( pCharToneSyllable + iNum, pDigitToneSyllable, iCount ); iNum += iCount; pCharToneSyllable[iNum++] = CombiningCharSet[wTone - '1']; // 插入组合音符 iCount = iLen - iCount; // 剩余字符个数 wcsncpy( pCharToneSyllable + iNum, pInsert, iCount ); iNum += iCount; break; } } // End for i if(i == ToneCharNum) { // 未发现可标调字符 return -2; // 音节错误 } } else if(wTone == '5') { // 轻声 wcsncpy( pCharToneSyllable + iNum, pDigitToneSyllable, iLen ); iNum += iLen; } else { return -2; // 音节错误 } if(pHyphen == NULL) { break; } else { pCharToneSyllable[iNum++] = '-'; pDigitToneSyllable = pHyphen + 1; } } // End While pCharToneSyllable[iNum] = 0; // 写入字符串结束标记 if(isUppercase) StringToUpper(pCharToneSyllable, pCharToneSyllable); // 大写字母形式 else StringToLower(pCharToneSyllable, pCharToneSyllable); // 小写字母形式 return iNum; } // 基于数字标调的汉语拼音串比较函数(新华字典序) INT Pinyin::PinyinCompare( const WCHAR* x, const WCHAR* y ) { INT iRank; if(x == NULL || wcslen(x) == 0) { if(y == NULL || wcslen(y) == 0) return 0; else return 1; } else if(y == NULL || wcslen(y) == 0) { return 1; } // 定位连接符 const WCHAR* pHyphenX = wcschr(x, '-'); const WCHAR* pHyphenY = wcschr(y, '-'); if(pHyphenX != NULL) // x为多音节 { if(pHyphenY != NULL) // y为多音节 { // 比较第一个音节 iRank = MonoSyllableCompare(x, pHyphenX - x, y, pHyphenY - y); if(iRank == 0) { // 继续比较其余音节 return PinyinCompare(pHyphenX + 1, pHyphenY + 1); } else return iRank; } else { // y为单音节 iRank = MonoSyllableCompare(x, pHyphenX - x, y, -1); return (iRank == 0) ? 1 : iRank; } } else if(pHyphenY != NULL) { // x为单音节,y为多音节 iRank = MonoSyllableCompare(x, -1, y, pHyphenY - y); return (iRank == 0) ? (-1) : iRank; } else { // x和y都是单音节 return MonoSyllableCompare(x, -1, y, -1); } } // 基于数字标调的单音节串比较函数(新华字典序) INT Pinyin::MonoSyllableCompare(const WCHAR* x, INT iLenX, const WCHAR* y, INT iLenY) { INT iFlagX = 0; INT iFlagY = 0; if(iLenX < 0)iLenX = wcslen(x); if(iLenY < 0)iLenY = wcslen(y); INT iMinLen = (iLenX < iLenY) ? iLenX : iLenY; for(INT i = 0; i < iMinLen; i++) { WCHAR wCodeX = x[i]; WCHAR wCodeY = y[i]; if(wCodeX == 0x00CA || wCodeX == 0x00EA) { wCodeX = 'E'; iFlagX = 1; } else if(wCodeX == 0x00DC || wCodeX == 0x00FC) { wCodeX = 'U'; iFlagX = 1; } else if( wCodeX >= 'a' && wCodeX <= 'z') { wCodeX -= ('a' - 'A'); // 大写字母 } if(wCodeY == 0x00CA || wCodeY == 0x00EA) { wCodeY = 'E'; iFlagY = 1; } else if(wCodeY == 0x00DC || wCodeY == 0x00FC) { wCodeY = 'U'; iFlagY = 1; } else if(wCodeY >= 'a' && wCodeY <= 'z') { wCodeY -= ('a' - 'A'); } if(wCodeX < wCodeY) { // 特例:声调部分 if(iFlagX == 1 && iFlagY == 0) { if(wCodeX >= '1' && wCodeX <= '5' && wCodeY >= '1' && wCodeY <= '5') return 1; } return -1; } else if(wCodeX > wCodeY) { // 特例:声调部分 if(iFlagY == 1 && iFlagX == 0) { if(wCodeX >= '1' && wCodeX <= '5' && wCodeY >= '1' && wCodeY <= '5') return -1; } return 1; } } if(iFlagX == 1) { if(iFlagY == 1) return (iLenX < iLenY) ? (-1) : ((iLenX > iLenY) ? 1 : 0); else return 1; } else { if(iFlagY == 1) return -1; else return (iLenX < iLenY) ? (-1) : ((iLenX > iLenY) ? 1 : 0); } }
相关文章推荐
- 六一儿童节的礼物:基于GB18030-2000汉字拼音类库(C#)
- C#通用类库--汉字转拼音
- java 汉字基于拼音首字母检索
- C# 应用微软的Visual Studio International Pack 类库提取汉字拼音首字母
- Visual Studio International Pack 类库提取汉字拼音
- ASP.NET Core使用微软官方类库实现汉字转拼音
- 汉字转拼音的Java类库——JPinyin
- c++实现查找汉字拼音首字母
- C#获取汉字的拼音首字母帮助类库
- C/C++ 汉字转拼音
- C#通用类库--汉字转拼音
- C++实现查找汉字拼音首字母
- PHP基于自定义函数实现的汉字转拼音功能实例
- 根据汉字得到拼音的类库(一)
- C# 使用微软的Visual Studio International Pack 类库提取汉字拼音首字母
- 扩展类库:使用微软的 Visual Studio International Pack 1.0 进行网站简体与繁体的互转和得到汉字、拼音、笔画等相关信息
- 汉字转拼音的Java类库:JPinyin
- c++实现查找汉字拼音首字母
- C++汉字转拼音( 转)
- C# 使用微软的Visual Studio International Pack 类库提取汉字拼音首字母