汉字转拼音 自适应多音字处理 姓名自动切分
目录
2. 解释第一个问题(汉字转拼音使用一个函数就可以,为什么我的会有三个函数)
更新:现在已有c++,qt版本,js版本即将上传
一. 概要
如标题所示,本文的功能很明显
(*不用急着看代码,我会开源,并介绍使用方法,先看各种简介描述,看看是否是你需要的)
(*如果代码的下载量大,使用的人多,反馈的优化想法多,我会持久的更新,并且推出跨平台版本)
二. 适用场景
1.需要根据拼音或首字母,搜索包含姓名的列表
2.需要把汉字转换为拼音(自动解决多音字,姓氏特殊读音问题)
3.列表按照拼音首字母排序
4.姓、名自动切分
5.因系统不支持中文,需转换中文为拼音
三.代码运行效果
1. 获取输入姓名对应拼音的所有排列(列表搜索时使用),就一个函数,后面的注释就是运行结果,使用很简单。
速度粗糙大概估计(win10系统 + i5-8265U + 单线程下 + 每人3个字 => 50人/毫秒)
getComPingyinForStr("解红",fristPy,fullPy); // fristPy = "jg xg jh xh" , fullPy = "jiegong xiegong jiehong xiehong"
getComPingyinForStr("查查",fristPy,fullPy); // fristPy = "cc zc cz zz" , fullPy = "chacha zhacha chazha zhazha"
getComPingyinForStr("尉迟萌",fristPy,fullPy); // fristPy = "wcm ycm" , fullPy = "weichimeng yuchimeng"
getComPingyinForStr("李石",fristPy,fullPy); // fristPy = "ld ls" , fullPy = "lidan lishi"
getComPingyinForStr("小明",fristPy,fullPy); // fristPy = "xm" , fullPy = "xiaoming"
2.获取输入姓名的拼音(唯一的),和上面的区别就相当于,在所有的拼音组合中选择最正确的一个。(100人/毫秒)
一共有两个函数 myNameSplit(...)getNamePingyin(...) ,使用方法很明显。
QString names = { "东皇太一 尉迟小白 解波 卜艾 颜碧玉 句帅 杨红给 吕布 亚里士多缺德 覃黄埔 菊花拉姆 上官万" };
QStringList nameList = names.split(" ");
for (size_t i = 0; i < nameList.size(); i++)
{
QString full, fist, last;
full = nameList[i];
myNameSplit(full, last, fist); // 自动切分 [姓、名]
last = getNamePingyin(last, true); // 获取 [姓] 的拼音
fist = getNamePingyin(fist, false); // 获取 [名] 的拼音
qout << full + " : " + last + " " + fist << endl;
}
// 运行结果
"东皇太一 : donghuang taiyi"
"尉迟小白 : yuchi xiaobai"
"解波 : xie bo"
"卜艾 : bu ai"
"颜碧玉 : yan biyu"
"句帅 : gou shuai"
"杨红给 : yang honggei"
"吕布 : lv bu"
"亚里士多缺德 : ya lishiduoquede"
"覃黄埔 : qin huangpu"
"菊花拉姆 : juhua lamu"
"上官万 : shangguan wan"
*注意:qout => #define qout qDebug()
四.代码的原理
1. 到此为止,你可能会产生两个疑问:
a.汉字转拼音使用一个函数就可以,为什么我的会有三个函数
getComPingyinForStr() getNamePingyin() myNameSplit()
b.内部的原理实现原理是什么?
2. 解释第一个问题(汉字转拼音使用一个函数就可以,为什么我的会有三个函数)
a. 一对多:假如现在有一个列表,它有很多的姓名,我们想搜索出叫“解红”这个人,而“解”这个字有两个读音“xie jie”,你并不确定用户输入的拼音是什么(可能用户并不知道有多个读音),(红也是多音字“hong gong”),也就是说,我们要穷举所有可能的多音字排列。即:
getComPingyinForStr("解红",fristPy,fullPy); // fristPy = "jg xg jh xh" , fullPy = "jiegong xiegong jiehong xiehong"
b. 一对一:我现在想获取“解红”这个人的唯一拼音,虽然“解”是多音字,但是我们只能学选择一个读音,“红”也是同样的道理,我们知道“解”在做姓氏时读“xie”,"红"的常用读音是“hong”,所有输出结果因该是“xie hong”。
一个多音字在做[姓,名]时可能会有不同的读音,所以使用 myNameSplit() 切分输入姓名的[姓,名],然后再使用getNamePingyin()分别获取拼音。
c. 总结:使用三个函数实现所有功能并不过分
3. 内部时实现原理
在实现本功能之前,看过很多网上的资料与代码,总结下来,汉字转拼音有如下几种方式:
1. 查表:
但是有很多版本,他们使用的字库有的不完整,有的直接使用常用字库,也无法解决多音字问题,总之问题多,不能用。
2. 用一个长长的switch语句实现:
想要修改、补充根本不可能。
3.号称找到了,汉字编码与拼音的规律,直接计算出拼音:
这种只能查首字母,也无法决绝多音字问题。
本文的方法(特色):
1. 直接使用查表,虽然汉字编码有一定的规律但是意外情况太多。
2.使用权威的字库(新华字典http://xh.5156edu.com/pinyi.html),并修改官万的部分错误与缺失。
3.手动筛选所有的多音字(1000多个,很枯燥),建立多音字表,解决多音字问题。
4.收集姓氏特殊读音表,解决特殊姓氏的准确拼音输出。
5.收集复姓,自动切分 [姓、名]。
6.输出纯英文字符(例如:ü 用 v 代替)。
备注:
1. 本代码使用了Qt ,但只使用了 qstring、 qstringlist、 qvector,如果你不想使用qt,直接使用标准的c++也可,只需要做很少的改动,代码内部会说明改的思路,其实直接使用c++的标准库效率更高,我之所以使用Qt是因为项目的关系,如前面所说,如果下载量多,我会修改成标准的c++版本(不使用任何其他的库),这样移植起来更方便些。
2. 移植时可能会遇到的问题,IDE的默认编码问题。
vs2017+qt+修改vs2017默认编码为UTF8+本代码 => 直接通过
qtCreator+GUI程序+本代码 => 直接通过
移植的时候如果你直接使用qtCreator打开我的文件时,汉字可能是乱码的,
你需要用如下步骤:qtCreator上新建[h,cpp] 文件+[ctrl+A] + [ctrl+C] + [ctrl+V] 的方式,直到代码所有汉字显示正常,打印输出汉字正常为止。
产生乱码的原因就是vs2017和qtCreator的文本编码方式不一样,自行解决(不难)。
五.开源代码
1. 完整的代码下载连接
csdn:https://download.csdn.net/download/weixin_38887369/11234672
github:https://github.com/newMoonxx/ChineseToPinyin
(尽量去github,因为它支持增量式更新,github里面的代码一定是最新的)
2. 因为篇幅过长的原因(所有代码2000多行),所以这里只显示部分核心代码(省略各种表的细节,只象征性的显示几行),有个大概的了解即可,完整的内容自行下载咯。
*下面的图片是对应文件详细内容折叠后效果(方便你看到大纲),后面的代码是简化省略版。
头文件(省略版):
/*
0. 功能包括:自动分离姓名中的[姓,名];姓名转拼音(一对一,首字母+全拼音);姓名转拼音(一对多,首字母+全拼音)
1. 版本:V1.0 日期:2019年06月06日
2. 详情:
https://blog.csdn.net/weixin_38887369/article/details/91047524 // 本开源项目介绍
https://blog.csdn.net/weixin_38887369 //
3. 版权所有 qq:2271590144,新月
4. 使用语言:c++,使用库:qt
5. qt库只使用了 qstring qstringlist qvector,如果你不想使用qt,直接使用标准的c++也可,只需要做很少的改动
如果使用标准的c++库,改动如下:
qstring -> string
qstringlist -> vector<string>
qvector -> vector
a. cpp文件中的代码就300行左右,所以改动不多
b. [vector,qvector],[string,qstring] 的相似度极高,很多函数都是一样的,所以改起来也容易
c. 使用标准的string效率会更高
6. 实际运用测试:
a. 已经商用,没什么问题
b. 速度测试,环境:win10系统 + i5-8265U + 单线程下 + 每人3个字 ,很粗糙的速度测试结果如下
getComPingyinForStr() => 50 人/ms
getNamePingyin() => 100人/ms
7. 使用方法:可以直接看本文件(.h文件)的注释 或 进入详情页面开,见第二条的网址
*/
#pragma once
#include <qstring.h>
#include <qstringlist.h>
#include <qvector.h>
/*
0. vs2017的默认编码不是utf-8,如果在qt的IDE编辑不需要这句;如果在vs上开发并且不用qt,也不需要这句
1. 我是在vs2017上使用qt, 如果没有这句,则QString str="哈哈"; str会是乱码的
2. 如果你要使用CString ,则自己脑部...
*/
#pragma execution_character_set("utf-8") //
// 汉字-拼音
struct hanziTableS
{
// 拼音
QString first_py; // 首字母
QString full_py; // 全拼
// 汉字
QString hanzis;
};
// 特殊姓氏发音
struct lastNameTableS
{
QString hanzi;
QString pinyi;
};
// 常用多音字
struct multiToneWordTableS
{
QString hanzi;
QString pinyi;
};
// ----- 外部使用 ----- //
/*
0. 获取组合拼音(一可能对多),用于搜索
1. eg:
getComPingyinForStr("解红",fristPy,fullPy); // fristPy = "jg xg jh xh" , fullPy = "jiegong xiegong jiehong xiehong"
getComPingyinForStr("查查",fristPy,fullPy); // fristPy = "cc zc cz zz" , fullPy = "chacha zhacha chazha zhazha"
getComPingyinForStr("尉迟萌",fristPy,fullPy); // fristPy = "wcm ycm" , fullPy = "weichimeng yuchimeng"
getComPingyinForStr("李石",fristPy,fullPy); // fristPy = "ld ls" , fullPy = "lidan lishi"
getComPingyinForStr("小明",fristPy,fullPy); // fristPy = "xm" , fullPy = "xiaoming"
*/
int getComPingyinForStr(const QString& inStr, QString& outFrist_py, QString& outFull_py);//ok
/*
0. 【姓、名】分别转拼音(严格的一一对应),用于汉字强转拼音
1. 使用了:姓氏特殊读音字库 + 多音字常用读音字库 + 全字库
2. eg:
str = getNamePingyin("春",true); // str => "chun"
str = getNamePingyin("春",false); // str => "chun"
str = getNamePingyin("解",true); // str => "xie"
str = getNamePingyin("解",false); // str => "jie"
str = getNamePingyin("翟",true); // str => "zhai"
str = getNamePingyin("翟",false); // str => "di"
str = getNamePingyin("参",true); // str => "can"
str = getNamePingyin("参",false); // str => "can"
str = getNamePingyin("单于",true); // str => "chanyu"
str = getNamePingyin("单于",false); // str => "danyu"
*/
QString getNamePingyin(const QString& inStr, bool isLastName);//
/*
0. 自动切分 姓、名
1. 基本只能应对普通的复姓(两个字),如果在复姓表中没有找到,则: 姓氏 = (fullName.size() == 4) ? fullName的前两个个字符 : fullName的第一个字符
2. 备注:百度的姓氏基本就70多个,这里有90个,但是忽略的少数民族的姓氏,也不要认为复姓就是两个字,(《中国少数民族姓氏》汇总大概有1万多)
例如:乌拉乌拉氏、爱新觉罗、钮钴禄、色氏、尼玛(我见过很多姓这个的)
3. eg:
QString names = {"东皇太一 尉迟小白 解波 卜艾 颜碧玉 句帅 杨红给 吕布 亚里士多缺德 覃黄埔 菊花拉姆 上官万"};
QStringList nameList = names.split(" ");
for (size_t i = 0; i < nameList.size(); i++)
{
QString full, fist, last;
full = nameList[i];
myNameSplit(full, last, fist);
last = getNamePingyin(last, true);
fist = getNamePingyin(fist, false);
qout << full + " : " + last + " " + fist << endl;
}
// 结果
"东皇太一 : donghuang taiyi"
"尉迟小白 : yuchi xiaobai"
"解波 : xie bo"
"卜艾 : bu ai"
"颜碧玉 : yan biyu"
"句帅 : gou shuai"
"杨红给 : yang honggei"
"吕布 : lv bu"
"亚里士多缺德 : ya lishiduoquede"
"覃黄埔 : qin huangpu"
"菊花拉姆 : juhua lamu"
"上官万 : shangguan wan"
*/
void myNameSplit(const QString& inFullName, QString& outLastName, QString& outFirstName);
// ----- 内部部使用 ----- //
/*
0. 获取一个汉字的【所有】拼音(首字母、全拼)
1. 使用字库 : hanziTables[]
2. 输出不会为空,除非输入就等于空
3. 如果输入为非中文字符,则返回和输入一样
4. inWord 只能输入一个汉字,否则返回-1
5. eg:
getAllPingyinForWord("句",fristPy,fullPy); // fristPy => {"g","j"} , fullPy => {"gou","ju"}
getAllPingyinForWord("龙",fristPy,fullPy); // fristPy => {"l"} , fullPy => {"long"}
*/
int getAllPingyinForWord(const QString& inWord, QStringList& outFrist_py, QStringList& outFull_py); // ok
/*
0. 获取一个字的拼音,如果是多音字返回常用读音
1. 偏向于名的发音偏好,而不是姓氏的发音偏好
2. 输出不会为空,除非输入就等于空
3. 使用字库:multiToneWordTable[](多音字库)+ hanziTables[](全字库)
4. 如果输入为非中文字符,则返回和输入一样
5. 多音字的取舍规则见:multiToneWordTable[]
6. inWord 只能输入一个汉字,否则直接放回输入内容
7. eg:
str = getNoRepeatPingyinForWord("大"); // str => "da"
str = getNoRepeatPingyinForWord("解"); // str => "jie"
str = getNoRepeatPingyinForWord("石"); // str => "shi"
*/
QString getNoRepeatPingyinForWord(const QString& inWord);//ok
源文件(省略版):
#include "myPinyin.h"
#define g_length_lastNameTable 554
#define g_length_multiToneWordTable 708
#define g_length_hanziTables 411
/*
0. 姓氏特殊读音(包括:特殊、非特殊、复姓读音)
1. 可以自己添加
3. 来源于各种网络数据的整合
*/
lastNameTableS lastNameTable[g_length_lastNameTable] =
{
{ "赵" , "zhao" },
{ "钱" , "qian" },
{ "孙" , "sun" },
{ "羊角" , "yangjue" },
{ "中行" , "zhonghang" },
{ "禚" , "zhuo" },
{ "迮" , "ze" },
{ "覃" , "qin" },
......
};
/*
0. 多音字表
1. 后面的注释表示的是:这个字剩余的其他读音 (日、韩分别表示汉字是日语或韩语)
2. 来源于 hanziTables[],(遍历的所有,没有遗漏)
3. 多音字选中读音规则:
a. 选择常用读音 :
{ "红" , "hong" }, // gong
{ "薄" , "bo" }, // bao
{ "拆" , "chai" }, // ca
b. 选择根据拼音可以猜出汉字的读音。这种字大家知道是多音字,如果我输出'ju'你基本可以猜到汉字'句',但是我输出'gou'你还能猜到汉字是'句'就...
{ "句" , "ju" }, // gou
{ "旁" , "pang" }, // bang
{ "给" , "gei" }, // ji
{ "艾" , "ai" }, // yi
{ "大" , "da" }, // dai
{ "炮" , "pao" }, // bao
c. 选中非姓氏读音
{ "仇" , "chou" }, // qiu ,仇:作姓氏时读qiú
{ "解" , "jie" }, // xie ,解:作姓氏时读xiè
{ "曾" , "ceng" }, // zeng,曾:作姓氏时读zēng
d. 选中姓名中比较可能出现的字,下面的例子可能恰好符合其他的规则,但是在我手动筛选多音字时确实考虑到这方面的情况,因为有些多音字的其中一些读音代表的意义明显不可能被当名字来使用,因为筛选时没记录,下面的例子可能不贴切
{ "盛" , "sheng" }, // cheng , 茂盛(maoSheng),盛饭(chengFan)
{ "石" , "shi" }, // dan , 潘石屹
{ "矜" , "jin" }, // qin guan
{ "强" , "qiang" }, // jiang , 坚强(qiang),倔强(jiang)
e. 需要上下文联系的,这种字没法了,只能查表,这里的输出原则遵循(abcd)
{ "屏" , "ping" }, // bing , 屏幕、屏弃
{ "卜" , "bu" }, // bo , 占卜、萝卜
*/
multiToneWordTableS multiToneWordTable[g_length_multiToneWordTable] =
{
{ "厑" , "e" }, // si a
{ "吖" , "ya" }, // a
{ "阿" , "a" }, // e
{ "凹" , "ao" }, // wa
{ "嚣" , "xiao" }, // ao
{ "夭" , "ao" }, // yao
{ "伯" , "bo" }, // bai ba
{ "大" , "da" }, // dai
{ "弹" , "tan" }, // dan
{ "般","ban" }, // bo pan
{ "剥","bao" }, // bo
......
};
/*
0. 汉字拼音表,来源于 http://xh.5156edu.com/pinyi.html (需要自己获取数据)
1. 在'bo'添加'卜' ; 'de'添加'的' ; 'wan'添加'涴' (获取到的数据有缺失,是网站的问题,这里直接补全)
2. ü 用 v 代替
*/
hanziTableS hanziTables[g_length_hanziTables] =
{
{ "a","a","吖阿呵啊腌锕錒嗄厑" },
{ "a","ao","凹柪梎軪熬爊敖厫隞蔜遨廒嗷嗸獓嶅滶獒摮璈磝螯聱翱翶謷謸鳌翺嚣鏖鷔鰲鼇艹夭芺抝拗袄镺媪媼襖岙岰垇坳傲奡奥奧骜嫯慠懊墺澳嶴擙鏊驁澚鱜" },
{ "a","ang","肮骯卬仰岇昂昻枊盎醠" },
{ "a","ai","哎哀诶唉娭挨埃溾嗳锿鎄捱皑啀凒溰敱敳嘊皚癌騃佁毐昹欸娾矮蔼躷噯濭藹譪霭靄艾阨伌爱砹硋隘嗌嫒塧碍愛叆暧瑷僾噫壒懓嬡薆鴱餲璦曖懝皧瞹馤礙譺鑀靉閊魞﨟鱛鱫" },
{ "a","an","厂广安侒峖桉氨庵偣谙菴萻葊媕腤痷鹌誝蓭鞍鞌諳盦馣鮟盫鵪鶕韽玵啽雸儑垵俺唵埯铵晻揞罯銨屵犴岸按洝荌胺豻案婩隌堓暗貋錌闇黯" },
{ "b","bai","挀掰白犤百伯佰陌柏栢捭絔摆擺襬庍呗拝败拜敗猈稗粺薭贁韛瓸竡粨兡" },
{ "b","ba","丷八仈巴叭朳玐吧岜扷芭夿疤柭釟蚆粑笆捌哵羓豝鲃叐茇妭拔炦胈癹菝軷詙跋颰魃鼥把钯鈀靶伯弝坝爸杷垻罢耙跁鲅罷鮁覇矲霸壩灞欛抜鎺鯐" },
......
{ "z","zuo","作嘬穝昨莋秨笮捽琢筰鈼稓左佐撮繓阼坐怍岞岝侳祚胙袏座唑做葃葄飵糳咗" }
};
int getComPingyinForStr(const QString & inStr, QString & outFrist_py, QString & outFull_py)
{
// --- 条件返回
outFrist_py.clear();
outFull_py.clear();
if (inStr.isEmpty())
{
return -1;
}
// --- 获取每个字的所有读音
int numOfWord = inStr.size();
QVector<QStringList> fristPys;
QVector<QStringList> fullPys;
for (int i_word = 0; i_word < numOfWord; i_word++)
{
QStringList fristPy;
QStringList fullPy;
getAllPingyinForWord(inStr.at(i_word), fristPy, fullPy);
fristPys.push_back(fristPy);
fullPys.push_back(fullPy);
}
// --- 开始排列组合
QVector<int> nowIndexList;
QVector<int> maxIndexList;
int sum_maxIndexList = 0;
for (size_t i = 0; i < numOfWord; i++)
{
nowIndexList.push_back(0);
maxIndexList.push_back(fullPys[i].size() - 1);
sum_maxIndexList += maxIndexList[i];
}
// --- 第一次组合(所有采用第一个)
bool mustCombination = sum_maxIndexList > 0 ? true : false;
for (size_t i = 0; i < numOfWord; i++)
{
outFrist_py += fristPys[i][0];
outFull_py += fullPys[i][0];
}
// --- 循环遍历
while (mustCombination)
{
// --- 组合排列
bool alreadyRunOnce = false;
for (size_t i = 0; i < numOfWord; i++)
{
if (alreadyRunOnce)
{
break;
}
if (maxIndexList[i] != 0)
{
if (nowIndexList[i] < maxIndexList[i])
{
alreadyRunOnce = true;
nowIndexList[i]++;
}
else if (nowIndexList[i] == maxIndexList[i])
{
nowIndexList[i] = 0;
}
}
}
// --- 组合输出字符
outFrist_py += " ";
outFull_py += " ";
for (size_t i = 0; i < numOfWord; i++)
{
outFrist_py += fristPys[i][nowIndexList[i]];
outFull_py += fullPys[i][nowIndexList[i]];
}
// --- 退出条件
bool canOut = true;
for (size_t i = 0; i < numOfWord; i++)
{
if (nowIndexList[i] != maxIndexList[i])
{
canOut = false;
break;
}
}
if (canOut)
{
break;
}
}
// --- 返回
return 0;
}
QString getNamePingyin(const QString & inStr, bool isLastName)
{
QString outStr;
// ----- 姓氏
if (isLastName)
{
// --- 在百家姓中查找
for (size_t i = 0; i < g_length_lastNameTable; i++)
{
if (inStr == lastNameTable[i].hanzi)
{
outStr = lastNameTable[i].pinyi;
break;
}
}
}
// --- 直接汉字库查找
if (outStr.isEmpty())
{
for (int i = 0; i < inStr.size(); i++)
{
outStr += getNoRepeatPingyinForWord(inStr[i]);
}
}
return outStr;
}
void myNameSplit(const QString & inFullName, QString & outLastName, QString & outFirstName)
{
const int doubleLastNameLength = 90;
static QString doubleLastName[doubleLastNameLength] =
{
"欧阳" , "太史" , "端木" , "上官" , "司马" , "东方" , "独孤" , "南宫" , "万俟" , "闻人" ,
"夏侯" , "诸葛" , "尉迟" , "公羊" , "赫连" , "澹台" , "皇甫" , "宗政" , "濮阳" , "公冶" ,
"太叔" , "申屠" , "公孙" , "慕容" , "仲孙" , "钟离" , "长孙" , "宇文" , "司徒" , "鲜于" ,
"司空" , "闾丘" , "子车" , "亓官" , "司寇" , "巫马" , "公西" , "颛孙" , "壤驷" , "公良" ,
"漆雕" , "乐正" , "宰父" , "谷梁" , "拓跋" , "夹谷" , "轩辕" , "令狐" , "段干" , "百里" ,
"呼延" , "东郭" , "南门" , "羊舌" , "微生" , "公户" , "公玉" , "公仪" , "梁丘" , "公仲" ,
"公上" , "公门" , "公山" , "公坚" , "左丘" , "公伯" , "西门" , "公祖" , "第五" , "公乘" ,
"贯丘" , "公皙" , "南荣" , "东里" , "东宫" , "仲长" , "子书" , "子桑" , "即墨" , "达奚" ,
"褚师" , "吴铭" , "纳兰" , "归海" , "东皇" , "泽翁" , "阿扎" , "泽朗" , "索朗" , "邓真"
};
// --- 如果有非汉字字符,直接返回
for (size_t i = 0; i < inFullName.length(); i++)
{
ushort uni = inFullName.at(i).unicode();
if (uni < 0x4E00 || uni > 0x9FA5)
{
outLastName = "";
outFirstName = inFullName;
return;
}
}
//
outLastName = "";
outFirstName = "";
if (inFullName.isEmpty())
{
}
else if (inFullName.length() == 1)
{
outFirstName = inFullName;
}
else if (inFullName.length() == 2)
{
outLastName = inFullName.at(0);
outFirstName = inFullName.at(1);
}
else
{
QString guessLastName = inFullName.mid(0,2);
for (int i = 0; i < doubleLastNameLength; i++)
{
if (guessLastName == doubleLastName[i])
{
outLastName = doubleLastName[i];
outFirstName = inFullName.mid(2);
break;
}
}
if (outLastName.isEmpty())
{
if (inFullName.length() == 4)
{
outLastName = inFullName.mid(0,2);
outFirstName = inFullName.mid(2);
}
else
{
outLastName = inFullName.at(0);
outFirstName = inFullName.mid(1);
}
}
}
}
int getAllPingyinForWord(const QString& inWord, QStringList& outFrist_py, QStringList& outFull_py)
{
//
static Qt::CaseSensitivity cs = Qt::CaseSensitive;
// 只能输入一个字符
if (inWord.size() > 1)
{
return -1;
}
//
outFrist_py.clear();
outFull_py.clear();
ushort uni = inWord[0].unicode();
if (uni >= 0x4E00 && uni <= 0x9FA5)
{
for (int index_table = 0; index_table < g_length_hanziTables; index_table++)
{
if (hanziTables[index_table].hanzis.indexOf(uni, 0, cs) != -1)
{
outFrist_py.append(hanziTables[index_table].first_py);
outFull_py.append(hanziTables[index_table].full_py);
}
}
}
if (outFrist_py.isEmpty())
{
outFrist_py.append(inWord);
}
if (outFull_py.isEmpty())
{
outFull_py.append(inWord);
}
return 0;
}
QString getNoRepeatPingyinForWord(const QString& inWord)
{
QString outPingyin;
// 只能输入一个字符
if (inWord.size() > 1)
{
return inWord;
}
// ----- 先在多音字里面查询
for (int i = 0; i < g_length_multiToneWordTable; i++)
{
if (inWord == multiToneWordTable[i].hanzi)
{
outPingyin = multiToneWordTable[i].pinyi;
break;
}
}
// ----- 继续查询
if (!outPingyin.isEmpty())
{
return outPingyin;
}
// ----- 在全字库查找
static Qt::CaseSensitivity cs = Qt::CaseSensitive;
ushort uni = inWord[0].unicode();
if (uni >= 0x4E00 && uni <= 0x9FA5)
{
for (int index_table = 0; index_table < g_length_hanziTables; index_table++)
{
if (hanziTables[index_table].hanzis.indexOf(uni, 0, cs) != -1) // QString.contains() 内部调用indexOf(), 所以这里直接使用indexOf()
{
outPingyin = hanziTables[index_table].full_py;
break;
}
}
}
//
if (outPingyin.isEmpty())
{
outPingyin = inWord;
}
// ----- 返回结果
return outPingyin;
}
六.总结
1. 到此为止所有的使用方法(看头文件即可) 和 代码原理已近讲解完毕。
2. 如果你有更好的想法或改进的建议,请告诉我。
3. 真如开始所说的,如果使用的人多,反馈的优化想法多,我会持久的更新,并且推出跨平台版本(纯c++版本,方便移植)。
4. 原创不易,转载注明。