c++qt汉字转拼⾳⾃适应多⾳字处理姓名⾃动切分开源代码                                                                    汉字转拼⾳ ⾃适应多⾳字处理 姓名⾃动切分
⽬录
更新:现在已有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. 直接使⽤查表,虽然汉字编码有⼀定的规律但是意外情况太多。
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. 完整的代码下载连接
(尽量去github,因为它⽀持增量式更新,github⾥⾯的代码⼀定是最新的)
2. 因为篇幅过长的原因(所有代码2000多⾏),所以这⾥只显⽰部分核⼼代码(省略各种表的细节,只象征性的显⽰⼏⾏),有个⼤概的了解即可,完整的内容⾃⾏下载咯。
*下⾯的图⽚是对应⽂件详细内容折叠后效果(⽅便你看到⼤纲),后⾯的代码是简化省略版。
头⽂件(省略版):
/*
0. 功能包括:⾃动分离姓名中的[姓,名];姓名转拼⾳(⼀对⼀,⾸字母+全拼⾳);姓名转拼⾳(⼀对多,⾸字母+全拼⾳)
1. 版本:V1.0  ⽇期:2019年06⽉06⽇
2. 详情:
blog.csdn/weixin_38887369/article/details/91047524  // 本开源项⽬介绍
blog.csdn/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:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。