65,186
社区成员




/*
【编程题】(满分19分)
在很多软件中,输入拼音的首写字母就可以快速定位到某个词条。
比如,在铁路售票软件中,输入: “bj”就可以定位到“北京”。怎样在自己的软件中实现这个功能呢?
问题的关键在于:对每个汉字必须能计算出它的拼音首字母。
GB2312汉字编码方式中,一级汉字的3755个是按照拼音顺序排列的。
我们可以利用这个特征,对常用汉字求拼音首字母。
GB2312编码方案对每个汉字采用两个字节表示。
第一个字节为区号,第二个字节为区中的偏移号。为了能与已有的ASCII编码兼容(中西文混排),
区号和偏移编号都从0xA1开始。
我们只要找到拼音a,b,c,...x,y,z 每个字母所对应的GB2312编码的第一个汉字,
就可以定位所有一级汉字的拼音首字母了(不考虑多音字的情况)。下面这个表给出了前述信息。
请你利用该表编写程序,求出常用汉字的拼音首字母。
a 啊 B0A1
b 芭 B0C5
c 擦 B2C1
d 搭 B4EE
e 蛾 B6EA
f 发 B7A2
g 噶 B8C1
h 哈 B9FE
j 击 BBF7
k 喀 BFA6
l 垃 C0AC
m 妈 C2E8
n 拿 C4C3
o 哦 C5B6
p 啪 C5BE
q 期 C6DA
r 然 C8BB
s 撒 C8F6
t 塌 CBFA
w 挖 CDDA
x 昔 CEF4
y 压 D1B9
z 匝 D4D1
【输入、输出格式要求】
用户先输入一个整数n (n<100),表示接下来将有n行文本。
接着输入n行中文串(每个串不超过50个汉字)。
程序则输出n行,每行内容为用户输入的对应行的汉字的拼音首字母。
字母间不留空格,全部使用大写字母。
例如:
用户输入:
3
大家爱科学
北京天安门广场
软件大赛
则程序输出:
DJAKX
BJTAMGC
RJDS
【注意】
请仔细调试!您的程序只有能运行出正确结果的时候才有机会得分!
在评卷时使用的输入数据与试卷中给出的实例数据可能是不同的。
请把所有函数写在同一个文件中,调试好后,拷贝到【考生文件夹】下对应题号的“解答.txt”中即可。
相关的工程文件不要拷入。
源代码中不能使用诸如绘图、Win32API、中断调用、硬件操作或与操作系统相关的API。
允许使用STL类库,但不能使用MFC或ATL等非ANSI c++标准的类库。
例如,不能使用CString类型(属于MFC类库),不能使用randomize, random函数(不属于ANSI C++标准)
*/
#include <iostream>
#include<string>
#include<vector>
using namespace std;
enum Letter{
A = 0XB0A1,B = 0XB0C5,C = 0XB2C1,
D = 0XB4EE,F = 0XB7A2,G = 0XB8C1,
H = 0XB9FE,J = 0XBBF7,K = 0XBFA6,
L = 0XC0AC,M = 0XC2E8,N = 0XC4C3,
O = 0XC5B6,P = 0XC5BE,Q = 0XC6DA,
R = 0XC8BB,S = 0XC8F6,T = 0XCBFA,
W = 0XCDDA,X = 0XCEF4,Y = 0XD1B9,
Z = 0XD4D1
};
char fun(Letter temp)
{
if(temp < B) return 'A';
if(temp < C) return 'B';
if(temp < D) return 'C';
if(temp < F) return 'D';
if(temp < G) return 'F';
if(temp < H) return 'G';
if(temp < J) return 'H';
if(temp < K) return 'J';
if(temp < L) return 'K';
if(temp < M) return 'L';
if(temp < N) return 'M';
if(temp < O) return 'N';
if(temp < P) return 'O';
if(temp < Q) return 'P';
if(temp < R) return 'Q';
if(temp < S) return 'R';
if(temp < T) return 'S';
if(temp < W) return 'T';
if(temp < X) return 'W';
if(temp < Y) return 'X';
if(temp < Z) return 'Y';
return 'Z';
}
int main()
{
int n;
cin >> n;
wstring s;
while(n--)
{
//cout << sizeof(0xB0A1) << endl << "wchar_t :"<< sizeof(wchar_t) << endl << "Letter : " << sizeof(Letter) << endl;
wcin >> s;
//wcout << s;
int len = s.size();
//cout << len << endl;
string ans;
for(int i = 0;i < len;i ++)
{
//Letter temp = static_cast<Letter>(static_cast<Letter>(s[i] << 16) + static_cast<Letter>(s[i + 1]));
//ans.push_back(fun(temp));
wcout << s[i];
//cout << cout.setf(ios::hex) << s[i] << ",";
ans += fun((Letter)s[i]);
//cout << cout.setf( ios::hex)<< int32_t(temp);
//ans += fun(temp);
}
cout << endl;
cout << ans << endl;
}
return 0;
}
/*
int main()
{
int n;
cin >> n;
wstring s;
while(n--)
{
wcin >> s;
wcout << s;
int len = s.size();
string ans;
for(int i = 0;i < len;i ++)
{
ans += fun(Letter(s[i]));
}
cout << ans << endl;
}
return 0;
}*/
Public Function HzToPy(Hz As String, Optional Sep As String = "", Optional ShowNotation As Boolean = True, Optional ShowInitialOnly As Boolean, Optional ShowOnlyOneChar As Boolean = True) As String
Dim hp As HZ2PY
Set hp = New HZ2PY '创建类
If Sep <> "" Then
hp.Seperator = Sep
hp.UseSeperator = True
End If
hp.InitialOnly = ShowInitialOnly
hp.OnlyOneChar = ShowOnlyOneChar
HzToPy = hp.GetPinYin(Hz)
If Not ShowNotation Then HzToPy = hp.AdjustPhoneticNotation(HzToPy, pnNoNotation)
Set hp = Nothing '释放类
End Function
'***************************************************************************
'*
'* MODULE NAME: HzToPy
'* AUTHOR & DATE: tt.t
'* 03 Apirl 2007
'*
'* DESCRIPTION: 将中文字符串转换为拼音,就这些~
'* 有汉字得到拼音其实并不是我很关心的一个问题,只是发现已经公开
'* 的方法有很大的缺陷,但WORD却做得很好,因此才尝试解决这个问题。
'* 过程比我预期的要曲折的多,主要是VBA实在是一种很受限制的语言。
'* 不过好在有Google和Olldbg,难题也仅仅是如何找到绕过限制的途径,
'* 终于在5个小时内搞定了一切~
'* 时间比我预计的长了很多,因为我实在是不了解VBA,也不很熟悉OLE:"(
'* 不过好在一切都解决了~~终于从VBA小白成长了一些。
'* 其实VBA也是很强大的~
'*
'* Theory: 废话了好多还是说说原理吧,虽然不是每个人都很关心~
'* WORD的拼音向导能够将汉字转成拼音全是倚仗微软拼音的帮助,
'* 微软拼音2.0以上版本都提供了汉字到拼音的转换功能。
'* 微软拼音MSIME.China类中的IFELanguage接口具体实现了转换功能
'* 不过MSIME.China中没有提供IDispatch接口,VBA的CreateObject不支持
'* 调用这样的类,因此我们只好手工调用。CoCreateInstance可以创建类
'* 并获取IFELanguage接口,但我们无法直接调用,因为VBA不知道如何调用
'* IFELanguage接口的Method。这里困扰了我好久,原本希望能向其他语言那样
'* 声明接口结构,但VBA并不支持。万般无奈下只好在OLE相关DLL中寻找,期待能
'* 找到代理函数简介调用接口的Method。呵呵~功夫不负苦心人终于在OLEAUT32中
'* 找到了DispCallfunc。Google了一下,果然是我需要的。接口知道了,如何调用也
'* 清楚了,剩下的问题就是如何取得转换后的结果。IFELanguage.GetMorphResult会将
'* 转换的结果存在一个叫做tagMORRSLT的结构中,并返回指向tagMORRSLT的指针。
'* 新问题又来了,VBA不支持指针...sigh,为什么其他语言很容易实现的功能VBA用起来
'* 就这么烦呢~幸好VBA读取内存的限制也好突破,只需调用ntdll的RtlMoveMemory。
'* 好了~一切限制都已解除,HzToPy终于正常工作了~~
'* 说起来一切顺理成章,可是寻找解决方法的过程真的很痛苦,不过VBA经验值大涨也算有所收获。
'* 下面就让代码来说话吧。
'*
'* Memo: 改成类了,加入了拼音间加入分隔符和去掉注音的功能,请参照“模块1”中的例子,用起来很简单:)
'* 更正了一个错误,redim时vba数组默认起始搞错了
'*
'***************************************************************************
Option Explicit
Public Enum PhoneticNotation
pnDefault = 0
pnNoNotation = 1
End Enum
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type
Private Type TinyMORRSLT
dwSize As Long
pwchOutput As Long
cchOutput As Integer
End Type
Private Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function CoCreateInstance Lib "ole32" ( _
rclsid As GUID, ByVal pUnkOuter As Long, _
ByVal dwClsContext As Long, riid As GUID, _
ByRef ppv As Long) As Long
Private Declare Function DispCallFunc Lib "oleaut32" _
(ByVal pvInstance As Long, ByVal oVft As Long, _
ByVal cc As Long, ByVal vtReturn As Integer, _
ByVal cActuals As Long, prgvt As Integer, _
prgpvarg As Long, pvargResult As Variant) As Long
Private Declare Sub CoTaskMemFree Lib "ole32" (pv As Long)
Dim MSIME_GUID As GUID 'MSIME's GUID
Dim IFELanguage_GUID As GUID 'IFELanguage's GUID
Dim IFELanguage As Long 'Pointer to IFELanguage interface
Dim sNotation1
Dim sNotation2
Dim dNotation
Dim pvSeperator As String
Dim pvUseSeperator As Boolean
Dim pvInitialOnly As Boolean
Dim pvOnlyOneChar As Boolean
Private Sub InitalArray()
sNotation1 = Array("ā", "á", "ǎ", "à", "ē", "é", "ě", "è", "ī", "í", "ǐ", "ì", "ō", "ó", "ǒ", _
"ò", "ū", "ú", "ǔ", "ù", "ǖ", "ǘ", "ǚ", "ǜ", "ü", "", "ń", "ň", "", "ɡ")
sNotation2 = Array("a1", "a2", "a3", "a4", "e1", "e2", "e3", "e4", "i1", "i2", "i3", "i4", "o1", "o2", "o3", _
"o4", "u1", "u2", "u3", "u4", "v1", "v2", "v3", "v4", "v", "m2", "n2", "n4", "n2", "g")
dNotation = Array("a", "a", "a", "a", "e", "e", "e", "e", "i", "i", "i", "i", "o", "o", "o", _
"o", "u", "u", "u", "u", "v", "v", "v", "v", "v", "m", "n", "n", "n", "g")
End Sub
Private Sub GenGUID()
InitalArray
'MSIME.China GUID = "{E4288337-873B-11D1-BAA0-00AA00BBB8C0}"
With MSIME_GUID
.Data1 = &HE4288337
.Data2 = &H873B
.Data3 = &H11D1
.Data4(0) = &HBA
.Data4(1) = &HA0
.Data4(2) = &H0
.Data4(3) = &HAA
.Data4(4) = &H0
.Data4(5) = &HBB
.Data4(6) = &HB8
.Data4(7) = &HC0
End With
'IFELanguage GUID = "{019F7152-E6DB-11d0-83C3-00C04FDDB82E}"
With IFELanguage_GUID
.Data1 = &H19F7152
.Data2 = &HE6DB
.Data3 = &H11D0
.Data4(0) = &H83
.Data4(1) = &HC3
.Data4(2) = &H0
.Data4(3) = &HC0
.Data4(4) = &H4F
.Data4(5) = &HDD
.Data4(6) = &HB8
.Data4(7) = &H2E
End With
End Sub
Private Sub IFELanguage_Open()
Dim ret As Variant
DispCallFunc IFELanguage, 4, 4, vbLong, 0, 0, 0, ret
DispCallFunc IFELanguage, 12, 4, vbLong, 0, 0, 0, ret
End Sub
Private Sub IFELanguage_Close()
Dim ret As Variant
If IFELanguage = 0 Then Exit Sub
DispCallFunc IFELanguage, 8, 4, vbLong, 0, 0, 0, ret
DispCallFunc IFELanguage, 16, 4, vbLong, 0, 0, 0, ret
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Subroutine: GetPinYin
'''
''' Purpose: 返回汉字的拼音
'''
''' Arguments: HzStr - 待转换的拼音
'''
'''
''' Date Developer Action
''' --------------------------------------------------------------------------
''' 02 April 2007 tt.t 更正ReDim Py时的错误
'''
Private Function IFELanguage_GetMorphResult(HzStr As String) As String
Dim ret As Variant
Dim pArgs(0 To 5) As Long
Dim vt(0 To 5) As Integer
Dim Args(0 To 5) As Long
Dim ResultPtr As Long
Dim TinyM As TinyMORRSLT
Dim py() As Byte
Dim i As Integer
IFELanguage_GetMorphResult = ""
If IFELanguage = 0 Then Exit Function
Args(0) = &H30000
Args(1) = &H40000100
Args(2) = Len(HzStr)
Args(3) = StrPtr(HzStr)
Args(4) = 0
Args(5) = VarPtr(ResultPtr)
For i = 0 To 5
vt(i) = vbLong
pArgs(i) = VarPtr(Args(i)) - 8
Next
DispCallFunc IFELanguage, 20, 4, vbLong, 6, vt(0), pArgs(0), ret
MoveMemory TinyM, ByVal ResultPtr, 4 * 3
If TinyM.cchOutput > 0 Then
ReDim py(0 To TinyM.cchOutput * 2 - 1)
MoveMemory py(0), ByVal TinyM.pwchOutput, TinyM.cchOutput * 2
IFELanguage_GetMorphResult = py
End If
CoTaskMemFree (ResultPtr)
End Function
Private Function GetInitial(py As String) As String
Dim Char1 As String
Dim Char2 As String
Char1 = Left(py, 1)
Char2 = Mid(py, 2, 1)
GetInitial = Char1
If Not pvOnlyOneChar Then
Select Case Char1
Case "z", "c", "s"
If Char2 = "h" Then GetInitial = GetInitial + Char2
End Select
End If
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
''' Subroutine: GetPinYin
'''
''' Purpose: 返回汉字的拼音
'''
''' Arguments: HzStr - 待转换的拼音
'''
'''
''' Date Developer Action
''' --------------------------------------------------------------------------
''' 02 April 2007 tt.t Create
'''
Public Function GetPinYin(HzStr As String) As String
Dim i As Integer
Dim tmpStr As String
GetPinYin = ""
If HzStr <> "" Then
If pvUseSeperator Or pvInitialOnly Then
For i = 1 To Len(HzStr)
tmpStr = IFELanguage_GetMorphResult(Mid(HzStr, i, 1))
If tmpStr <> "" Then
If pvInitialOnly Then
GetPinYin = GetPinYin & GetInitial(tmpStr) & pvSeperator
Else
GetPinYin = GetPinYin & tmpStr & pvSeperator
End If
End If
Next
If Len(GetPinYin) > 0 Then GetPinYin = Left(GetPinYin, Len(GetPinYin) - 1)
Else
GetPinYin = IFELanguage_GetMorphResult(HzStr)
End If
End If
End Function
Public Function AdjustPhoneticNotation(Hz As String, pn As PhoneticNotation) As String
Dim i As Integer
AdjustPhoneticNotation = Hz
'未进行优化
Select Case pn
Case pnNoNotation
For i = LBound(dNotation) To UBound(dNotation)
AdjustPhoneticNotation = Replace(AdjustPhoneticNotation, sNotation1(i), dNotation(i))
Next
For i = LBound(dNotation) To UBound(dNotation)
AdjustPhoneticNotation = Replace(AdjustPhoneticNotation, sNotation2(i), dNotation(i))
Next
End Select
End Function
Private Sub Class_Initialize()
IFELanguage = 0
InitalArray
InitialOnly = False
GenGUID
If CoCreateInstance(MSIME_GUID, 0, 1, _
IFELanguage_GUID, IFELanguage) = 0 Then
IFELanguage_Open
pvUseSeperator = False
pvSeperator = " "
Else
Err.Raise "OLE error!!"
End If
End Sub
Private Sub Class_Terminate()
If IFELanguage <> 0 Then IFELanguage_Close
End Sub
Property Get Seperator() As String
Seperator = pvSeperator
End Property
Property Let Seperator(Value As String)
pvSeperator = Value
End Property
Property Get UseSeperator() As Boolean
UseSeperator = pvUseSeperator
End Property
Property Let UseSeperator(Value As Boolean)
pvUseSeperator = Value
End Property
Property Get InitialOnly() As Boolean
UseSeperator = pvInitialOnly
End Property
Property Let InitialOnly(Value As Boolean)
pvInitialOnly = Value
End Property
Property Get OnlyOneChar() As Boolean
UseSeperator = pvOnlyOneChar
End Property
Property Let OnlyOneChar(Value As Boolean)
pvOnlyOneChar = Value
End Property
// ConsoleApplicationTest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
int nsp[] = {
0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,
0xB8C1,0xB9FE,0xBBF7,0xBFA6,0xC0AC,0xC2E8,
0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB,0xC8F6,
0xCBFA,0xCDDA,0xCEF4,0xD1B9, 0xD4D1};
int nsc[] = {
'A','B','C','D','E','F',
'G','H','J','K','L','M',
'N','O','P','Q','R','S',
'T','W','X','Y','Z'};
struct ws {
char ch;
char cl;
};
union zh{
int c;
struct ws zc;
};
int _tmain(int argc, _TCHAR* argv[])
{
char data[100] = {0};
scanf("%s", data);
zh demo;
demo.c = 0;
demo.zc.ch= data[1];
demo.zc.cl = data[0];
for(int i = 0; i < 24; i++)
if(demo.c < nsp[i]){
printf("%c", nsc[i-1]);
break;
}
return 0;
}