小谈“汉字转换成拼音(不带声调)”
2011-05-16 21:58
246 查看
(作者:finallyly出处:博客园转载请注明作者和出处)
把汉字转换成拼音,实际上是一个非技术活,无外乎查表而已。可能由于汉字拼音转换表资源比较宝贵的缘故,网络上开源的转换程序比较少。另外,网络上给出的码表,可能不能覆盖全部的多音字,生僻字,所以基于此类码表写成的程序,也就有一定的局限性。
本文给出一份完毕的,将汉字转换成无声调标注的拼音的设计思路、全部代码并且给出一份在一定程度上可用的汉字拼音转换表。
首先指出本文部分参考了
《Python返回汉字的汉语拼音(原创)》的汉字拼音转换表以及大概思路。
下面步入正轨
汉语拼音转换表的物理存储格式:(汉字+空格+汉字对应的拼音,多个候选读音用哪个空格隔开)
程序中的转换表用MAP保存,其数据格式为map<wstring,vector<string>>,wstring:键值;vector<string>候选读音
1.将硬盘中的码表读入内存voidStringManipulation::FormatPinYinMap(map<wstring,vector<string>>&hptable)
{
ifstreamifile("mycodebook.txt");
stringline;
while(getline(ifile,line))
{
if(!line.empty())
{wstringwsResult=String2Wstring(line);
vector<wstring>goodWordstemp;
boost::split(goodWordstemp,wsResult,boost::is_any_of(""));
wstringmykey=goodWordstemp[0];
vector<string>myval;
for(vector<wstring>::iteratorit=goodWordstemp.begin()+1;it!=goodWordstemp.end();it++)
{
myval.push_back(Wstring2String(*it));
}
if(!hptable.count(mykey))
{
hptable[mykey]=myval;
}
}
}
}
2.将单个汉字转换成拼音的代码
vector<string>StringManipulation::HZ2Py(wstringcharacter,map<wstring,vector<string>>&hptable)
{
vector<string>candidates;
if(hptable.count(character))
{
candidates=hptable[character];
}
else
{
candidates.push_back("[A-Z]+");
}
returncandidates;
}3.将汉字字符串转换成对应的拼音字符串(重点函数)此份代码可以将任意汉字串转换成拼音。但是,工作侧重点是将汉语人名转换成拼音形式,从而构造启发式查询。考虑到多音字,生僻字等多种情形,为了让转换成的拼音字符串更具鲁棒性,我们在转换后的拼音串中加入了若干正则表达式比如我们将“刘禹锡”转换成”LIU.*?YU.*?XI”。这样形成的拼音字符串既可以和含有“liuyuxi”网页匹配,又可以和含有”LIUYUXI”网页匹配。汉语字符串中含有多音字的时候,可以形成多个候选读音。由于我们事先并不知道那些字是多音字,所有我们不可能事先确定一个汉字串究竟有多少种候选读音。这里采用的办法是:生成一个图来表示每个汉字对应的后续读音,以及这些读音之间的有向连接关系。然后用求有向图上任意两点间的所有路径的算法见《求两点之间所有路径的算法》,求出一个汉字字符串所对应的所有候选读音。
/************************************************************************/
/*获得一汉字字符串的拼音串*/
/************************************************************************/
vector<string>StringManipulation::Han2Py(stringshan,map<wstring,vector<string>>&hptable)
{
vector<string>result;
GraphRepresentationgr;
gr.Vertex[0]="@";
intmycount=0;//是否添加“正则边”
intprevsize=0;//上一个汉字有几个读音
intlaslabel=0;//上一次节点编号的最大值
if(!shan.empty())
{
wstringwhan=String2Wstring(shan);
for(wstring::iteratorit=whan.begin();it!=whan.end();it++)
{
wstringtmp;
tmp.assign(1,*it);
vector<string>tmpcandidates=HZ2Py(tmp,hptable);
if(mycount==0)
{
for(inti=0;i<tmpcandidates.size();i++)
{
gr.Vertex[i+laslabel+1]=tmpcandidates[i];
gr.GraphR[make_pair(0,i+laslabel+1)]="&";
}
prevsize=tmpcandidates.size();
laslabel=tmpcandidates.size();
}
else
{
for(inti=0;i<tmpcandidates.size();i++)
{
gr.Vertex[i+laslabel+1]=tmpcandidates[i];
for(intj=laslabel;j>laslabel-prevsize;j--)
{
gr.GraphR[make_pair(j,i+laslabel+1)]=".*?";
}
}
laslabel+=tmpcandidates.size();
prevsize=tmpcandidates.size();
}
mycount++;
}
gr.Vertex[laslabel+1]="@";
for(intj=laslabel;j>laslabel-prevsize;j--)
{
gr.GraphR[make_pair(j,laslabel+1)]="&";
}
vector<vector<int>>paths;
gr.GetPaths(paths,0,laslabel+1);
for(vector<vector<int>>::iteratorit=paths.begin();it!=paths.end();it++)
{
deque<int>tmpque;
stringsinglecandidate;
for(vector<int>::reverse_iteratorrit=it->rbegin();rit!=it->rend();rit++)
{
tmpque.push_back(*rit);
if(tmpque.size()==2)
{
inttmp1=tmpque.front();
tmpque.pop_front();
singlecandidate+=gr.Vertex[tmp1];
inttmp2=tmpque.front();
stringedge=gr.GraphR[make_pair(tmp1,tmp2)];
singlecandidate+=edge;
}
}
TrimString(singlecandidate,"@");
TrimString(singlecandidate,"&");
result.push_back(singlecandidate);
}
}
returnresult;
}
其他辅助函数见《小谈汉字转换成拼音辅助函数和辅助类》汉字2拼音转换表http://files.cnblogs.com/finallyliuyu/mycodebook.rar主调函数:StringManipulationstrp;
map<wstring,vector<string>>h2ptable;
strp.FormatPinYinMap(h2ptable);
vector<string>result=strp.Han2Py("陈阿娇",h2ptable);
for(vector<string>::iteratorit=result.begin();it!=result.end();it++)
{
cout<<*it<<endl;
}效果:
把汉字转换成拼音,实际上是一个非技术活,无外乎查表而已。可能由于汉字拼音转换表资源比较宝贵的缘故,网络上开源的转换程序比较少。另外,网络上给出的码表,可能不能覆盖全部的多音字,生僻字,所以基于此类码表写成的程序,也就有一定的局限性。
本文给出一份完毕的,将汉字转换成无声调标注的拼音的设计思路、全部代码并且给出一份在一定程度上可用的汉字拼音转换表。
首先指出本文部分参考了
《
下面步入正轨
汉语拼音转换表的物理存储格式:(汉字+空格+汉字对应的拼音,多个候选读音用哪个空格隔开)
程序中的转换表用MAP保存,其数据格式为map<wstring,vector<string>>,wstring:键值;vector<string>候选读音
1.将硬盘中的码表读入内存
2.将单个汉字转换成拼音的代码
/*获得一汉字字符串的拼音串*/
/************************************************************************/
vector<string>StringManipulation::Han2Py(stringshan,map<wstring,vector<string>>&hptable)
{
vector<string>result;
GraphRepresentationgr;
gr.Vertex[0]="@";
intmycount=0;//是否添加“正则边”
intprevsize=0;//上一个汉字有几个读音
intlaslabel=0;//上一次节点编号的最大值
if(!shan.empty())
{
wstringwhan=String2Wstring(shan);
for(wstring::iteratorit=whan.begin();it!=whan.end();it++)
{
wstringtmp;
tmp.assign(1,*it);
vector<string>tmpcandidates=HZ2Py(tmp,hptable);
if(mycount==0)
{
for(inti=0;i<tmpcandidates.size();i++)
{
gr.Vertex[i+laslabel+1]=tmpcandidates[i];
gr.GraphR[make_pair(0,i+laslabel+1)]="&";
}
prevsize=tmpcandidates.size();
laslabel=tmpcandidates.size();
}
else
{
for(inti=0;i<tmpcandidates.size();i++)
{
gr.Vertex[i+laslabel+1]=tmpcandidates[i];
for(intj=laslabel;j>laslabel-prevsize;j--)
{
gr.GraphR[make_pair(j,i+laslabel+1)]=".*?";
}
}
laslabel+=tmpcandidates.size();
prevsize=tmpcandidates.size();
}
mycount++;
}
gr.Vertex[laslabel+1]="@";
for(intj=laslabel;j>laslabel-prevsize;j--)
{
gr.GraphR[make_pair(j,laslabel+1)]="&";
}
vector<vector<int>>paths;
gr.GetPaths(paths,0,laslabel+1);
for(vector<vector<int>>::iteratorit=paths.begin();it!=paths.end();it++)
{
deque<int>tmpque;
stringsinglecandidate;
for(vector<int>::reverse_iteratorrit=it->rbegin();rit!=it->rend();rit++)
{
tmpque.push_back(*rit);
if(tmpque.size()==2)
{
inttmp1=tmpque.front();
tmpque.pop_front();
singlecandidate+=gr.Vertex[tmp1];
inttmp2=tmpque.front();
stringedge=gr.GraphR[make_pair(tmp1,tmp2)];
singlecandidate+=edge;
}
}
TrimString(singlecandidate,"@");
TrimString(singlecandidate,"&");
result.push_back(singlecandidate);
}
}
returnresult;
}
map<wstring,vector<string>>h2ptable;
strp.FormatPinYinMap(h2ptable);
vector<string>result=strp.Han2Py("陈阿娇",h2ptable);
for(vector<string>::iteratorit=result.begin();it!=result.end();it++)
{
cout<<*it<<endl;
}
相关文章推荐
- C#汉字转换成拼音
- [转]汉字转换为拼音
- Java之——汉字转换拼音(大小写)
- 汉字转换为拼音
- Java 汉字转换为中文拼音的研究一:读取.db文件
- java代码将汉字转换成拼音
- 汉字转换为拼音
- 把我们的汉字转换成为以拼音首字母的关键字的方法
- 2-02串与数值转换(已更新)拼音查找汉字也是这个原理
- 支持 汉字 拼音 笔画 转换Microsoft Visual Studio International Pack 1.0 Beta1
- Microsoft Visual Studio International Pack 1.0 Beta1 处理汉字、拼音、笔画转换
- Javascript输入汉字自动转换为首字母的拼音码
- 【pinyin4j】使用pinyin4j将汉字转换为拼音
- 汉字转换为拼音(1)
- Java中汉字转换成拼音码!
- Java将汉字转换为拼音
- C#中汉字数字、汉字拼音的转换
- Java下将汉字转换为拼音的包pinyin4j
- 把汉字转换成拼音