六一儿童节的礼物:基于GB18030-2000汉字拼音类库(C++)

开发工具:

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);		
	}
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: ACIS-CAD编程类库是一种用于开发CAD软件的编程库。ACIS是几何建模内核,可以提供丰富的几何操作和分析功能,包括创建、编辑和查询几何实体,如点、线、面和立体等。而CAD编程类库则是基于ACIS内核的一组软件工具和功能,用于帮助开发者实现CAD软件的自定义和扩展。 ACIS-CAD编程类库可以在开发过程中提供很多优势。首先,它提供了底层的几何处理功能,使得开发者可以轻松地进行几何操作和计算,如形状的移动、旋、缩放和截取等。其次,ACIS-CAD编程类库还支持各种文件格式的导入和导出,例如DWG和STEP等,使得开发者可以方便地与其他CAD软件交互。此外,ACIS-CAD编程类库还提供了强大的三维可视化功能,可以实现高质量的渲染和显示,使得开发的CAD软件具有更好的用户体验。 使用ACIS-CAD编程类库可以实现各种各样的功能和扩展。例如,可以开发自定义的CAD工具和命令,用于快速创建和编辑几何实体。还可以实现各种算法,如碰撞检测、包围盒计算和曲面拟合等。此外,ACIS-CAD编程类库还可以用于开发CAD软件的插件和扩展,为用户提供更多的选择和功能。 综上所述,ACIS-CAD编程类库是一种强大的软件工具,可以帮助开发者快速而方便地创建、编辑和分析CAD软件中的几何实体。它的灵活性和可扩展性使得开发者可以实现各种定制化的功能和扩展,为用户提供更好的使用体验。 ### 回答2: ACIS-CAD编程类库是一种用于CAD软件开发的工具包。ACIS(三维CAD部分)是一个由Dassault Systemes公司开发的CAD内核,是许多主流CAD软件使用的核心技术。编程类库则是基于ACIS内核开发的一组API(应用程序接口),提供了丰富的CAD编程功能和工具,方便开发者通过编程来定制和扩展CAD软件的功能。 ACIS-CAD编程类库可以帮助开发者实现多种CAD相关功能,如模型创建和编辑、几何操作、实体选择、边界计算、坐标变换等。开发者可以使用ACIS-CAD编程类库中的API进行二次开发,定制CAD软件的功能和界面,满足特定的设计需求。同时,ACIS-CAD编程类库还提供了丰富的CAD数据交换功能,可以实现与其他CAD软件和数据格式的互操作性。 ACIS-CAD编程类库使用简单灵活,具有较高的性能和稳定性。通过使用该编程类库,开发者可以大大提高CAD软件的开发效率和功能扩展性。同时,ACIS-CAD编程类库还提供了丰富的文档和示例代码,帮助开发者快速入门和理解API的使用方法。 综上所述,ACIS-CAD编程类库是一种强大的CAD软件开发工具包,提供了丰富的API和功能,帮助开发者定制和扩展CAD软件的功能,提高开发效率和软件质量。使用该编程类库,开发者可以满足各种CAD软件开发需求,使其更加适应个性化的设计需求。 ### 回答3: ACIS-CAD编程类库是一种用于开发计算机辅助设计(CAD)软件的程序库。ACIS是Automated CONstrain-based Incremental Solver的缩写,意为自动基于约束的增量求解器。它是由Spatial Corporation开发的一套先进的三维几何建模和分析工具。 ACIS-CAD编程类库提供了一系列功能强大的API(应用程序接口),可以用于创建、编辑和分析三维几何模型。它支持多种CAD文件格式,并提供了高级的几何操作和分析功能,如布尔运算、曲线和曲面操作、造型和变换、碰撞检测等。 使用ACIS-CAD编程类库,开发人员可以轻松实现各种CAD软件的功能,包括绘图、构建模型、进行参数化设计、进行仿真和分析等。它还支持多线程编程,可以有效提高开发效率和运行速度。 ACIS-CAD编程类库具有良好的跨平台性能,可以在Windows、Linux和Mac等多个操作系统上运行。它还与其他常用的CAD软件和工具集成,如AutoCAD、SolidWorks、CATIA等。在CAD行业中被广泛应用,并得到了许多CAD软件开发公司和设计团队的青睐。 总之,ACIS-CAD编程类库是一种强大的软件开发工具,可用于构建CAD应用程序和开发各种CAD相关的功能。它的功能丰富、易用性强,并具有良好的跨平台性能,是CAD领域中不可或缺的重要组成部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值